Abstract

This report explores the relationships between various factors influencing student performance, using exploratory data analysis (EDA) to identify key trends and correlations. The analysis focuses on variables such as study habits, access to resources, parental involvement, and environmental factors, and how they impact final exam scores. Insights gained from the data will inform recommendations aimed at improving academic outcomes for students.

Data Source

The dataset was sourced from Kaggle under the CC0 1.0 universal “No Copyright” license. We are free to copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. Learn more about this license here here.

URL for data in Kaggle: Student Performance Factors Dataset

Import and View Data

student_data <- read.csv('../data/StudentPerformanceFactors.csv', header = TRUE)
student_data    # Display the dataset
sample_fraction <- 0.3

Summary Statistics

# Summary statistics for all variables
summary(student_data)   # Summary statistics for all variables
 Hours_Studied     Attendance     Parental_Involvement Access_to_Resources
 Min.   : 1.00   Min.   : 60.00   Length:6607          Length:6607        
 1st Qu.:16.00   1st Qu.: 70.00   Class :character     Class :character   
 Median :20.00   Median : 80.00   Mode  :character     Mode  :character   
 Mean   :19.98   Mean   : 79.98                                           
 3rd Qu.:24.00   3rd Qu.: 90.00                                           
 Max.   :44.00   Max.   :100.00                                           
 Extracurricular_Activities  Sleep_Hours     Previous_Scores 
 Length:6607                Min.   : 4.000   Min.   : 50.00  
 Class :character           1st Qu.: 6.000   1st Qu.: 63.00  
 Mode  :character           Median : 7.000   Median : 75.00  
                            Mean   : 7.029   Mean   : 75.07  
                            3rd Qu.: 8.000   3rd Qu.: 88.00  
                            Max.   :10.000   Max.   :100.00  
 Motivation_Level   Internet_Access    Tutoring_Sessions Family_Income     
 Length:6607        Length:6607        Min.   :0.000     Length:6607       
 Class :character   Class :character   1st Qu.:1.000     Class :character  
 Mode  :character   Mode  :character   Median :1.000     Mode  :character  
                                       Mean   :1.494                       
                                       3rd Qu.:2.000                       
                                       Max.   :8.000                       
 Teacher_Quality    School_Type        Peer_Influence     Physical_Activity
 Length:6607        Length:6607        Length:6607        Min.   :0.000    
 Class :character   Class :character   Class :character   1st Qu.:2.000    
 Mode  :character   Mode  :character   Mode  :character   Median :3.000    
                                                          Mean   :2.968    
                                                          3rd Qu.:4.000    
                                                          Max.   :6.000    
 Learning_Disabilities Parental_Education_Level Distance_from_Home
 Length:6607           Length:6607              Length:6607       
 Class :character      Class :character         Class :character  
 Mode  :character      Mode  :character         Mode  :character  
                                                                  
                                                                  
                                                                  
    Gender            Exam_Score    
 Length:6607        Min.   : 55.00  
 Class :character   1st Qu.: 65.00  
 Mode  :character   Median : 67.00  
                    Mean   : 67.24  
                    3rd Qu.: 69.00  
                    Max.   :101.00  
head(student_data)      # Display the first few rows of the dataset
str(student_data)       # Structure of the dataset
'data.frame':   6607 obs. of  20 variables:
 $ Hours_Studied             : int  23 19 24 29 19 19 29 25 17 23 ...
 $ Attendance                : int  84 64 98 89 92 88 84 78 94 98 ...
 $ Parental_Involvement      : chr  "Low" "Low" "Medium" "Low" ...
 $ Access_to_Resources       : chr  "High" "Medium" "Medium" "Medium" ...
 $ Extracurricular_Activities: chr  "No" "No" "Yes" "Yes" ...
 $ Sleep_Hours               : int  7 8 7 8 6 8 7 6 6 8 ...
 $ Previous_Scores           : int  73 59 91 98 65 89 68 50 80 71 ...
 $ Motivation_Level          : chr  "Low" "Low" "Medium" "Medium" ...
 $ Internet_Access           : chr  "Yes" "Yes" "Yes" "Yes" ...
 $ Tutoring_Sessions         : int  0 2 2 1 3 3 1 1 0 0 ...
 $ Family_Income             : chr  "Low" "Medium" "Medium" "Medium" ...
 $ Teacher_Quality           : chr  "Medium" "Medium" "Medium" "Medium" ...
 $ School_Type               : chr  "Public" "Public" "Public" "Public" ...
 $ Peer_Influence            : chr  "Positive" "Negative" "Neutral" "Negative" ...
 $ Physical_Activity         : int  3 4 4 4 4 3 2 2 1 5 ...
 $ Learning_Disabilities     : chr  "No" "No" "No" "No" ...
 $ Parental_Education_Level  : chr  "High School" "College" "Postgraduate" "High School" ...
 $ Distance_from_Home        : chr  "Near" "Moderate" "Near" "Moderate" ...
 $ Gender                    : chr  "Male" "Female" "Male" "Male" ...
 $ Exam_Score                : int  67 61 74 71 70 71 67 66 69 72 ...
sum(is.na(student_data))    # Check for missing values
[1] 0

Data Cleaning

Missing Values

We now check whether the dataset contains any missing values and remove them if necessary.

# Check missing values in each column
colSums(is.na(student_data))
             Hours_Studied                 Attendance 
                         0                          0 
      Parental_Involvement        Access_to_Resources 
                         0                          0 
Extracurricular_Activities                Sleep_Hours 
                         0                          0 
           Previous_Scores           Motivation_Level 
                         0                          0 
           Internet_Access          Tutoring_Sessions 
                         0                          0 
             Family_Income            Teacher_Quality 
                         0                          0 
               School_Type             Peer_Influence 
                         0                          0 
         Physical_Activity      Learning_Disabilities 
                         0                          0 
  Parental_Education_Level         Distance_from_Home 
                         0                          0 
                    Gender                 Exam_Score 
                         0                          0 

We can see that there are no missing values in the dataset.

We now check the unique values in each categorical column to identify any inconsistencies.

# Unique values in each categorical column
lapply(student_data[, sapply(student_data, is.character)], unique)
$Parental_Involvement
[1] "Low"    "Medium" "High"  

$Access_to_Resources
[1] "High"   "Medium" "Low"   

$Extracurricular_Activities
[1] "No"  "Yes"

$Motivation_Level
[1] "Low"    "Medium" "High"  

$Internet_Access
[1] "Yes" "No" 

$Family_Income
[1] "Low"    "Medium" "High"  

$Teacher_Quality
[1] "Medium" "High"   "Low"    ""      

$School_Type
[1] "Public"  "Private"

$Peer_Influence
[1] "Positive" "Negative" "Neutral" 

$Learning_Disabilities
[1] "No"  "Yes"

$Parental_Education_Level
[1] "High School"  "College"      "Postgraduate" ""            

$Distance_from_Home
[1] "Near"     "Moderate" "Far"      ""        

$Gender
[1] "Male"   "Female"
Low
Medium
High
High
Medium
Low
No
Yes
Low
Medium
High
Yes
No
Low
Medium
High
Medium
High
Low
Public
Private
Positive
Negative
Neutral
No
Yes
High School
College
Postgraduate
Near
Moderate
Far
Male
Female

From the results above we can Teacher_Quality, Parental_Education_Level and Distance_from_Home have missing values. We will now investigate further to see exactly what these missing values are.

# Check for missing values in Teacher_Quality
teacher_quality_missing <- student_data[student_data$Teacher_Quality == "",]
teacher_quality_missing
nrow(teacher_quality_missing)
[1] 78

We can see that only 78 rows have missing values in the Teacher_Quality column. We will now investigate the Parental_Education_Level column.

# Check for missing values in Parental_Education_Level
parental_education_level_missing <- student_data[student_data$Parental_Education_Level == "",]
parental_education_level_missing
nrow(parental_education_level_missing)
[1] 90

We can see that 90 rows have missing values in the Parental_Education_Level column. We will now investigate the Distance_from_Home column.

# Check for missing values in Distance_from_Home
distance_from_home_missing <- student_data[student_data$Distance_from_Home == "",]
distance_from_home_missing
nrow(distance_from_home_missing)
[1] 67

We can see that 67 rows have missing values in the Distance_from_Home column. All the missing values combined make up less than 10% of the dataset. We will remove these rows from the dataset.

# Remove rows with missing values
student_data <- subset(student_data, Teacher_Quality != "" & Parental_Education_Level != "" & Distance_from_Home != "")

# Check for missing values
lapply(student_data[, sapply(student_data, is.character)], unique)
$Parental_Involvement
[1] "Low"    "Medium" "High"  

$Access_to_Resources
[1] "High"   "Medium" "Low"   

$Extracurricular_Activities
[1] "No"  "Yes"

$Motivation_Level
[1] "Low"    "Medium" "High"  

$Internet_Access
[1] "Yes" "No" 

$Family_Income
[1] "Low"    "Medium" "High"  

$Teacher_Quality
[1] "Medium" "High"   "Low"   

$School_Type
[1] "Public"  "Private"

$Peer_Influence
[1] "Positive" "Negative" "Neutral" 

$Learning_Disabilities
[1] "No"  "Yes"

$Parental_Education_Level
[1] "High School"  "College"      "Postgraduate"

$Distance_from_Home
[1] "Near"     "Moderate" "Far"     

$Gender
[1] "Male"   "Female"
Low
Medium
High
High
Medium
Low
No
Yes
Low
Medium
High
Yes
No
Low
Medium
High
Medium
High
Low
Public
Private
Positive
Negative
Neutral
No
Yes
High School
College
Postgraduate
Near
Moderate
Far
Male
Female

Outliers

We now investigate the dependent variable, Final_Exam_Score, to identify any outliers.

# Outliers in Final_Exam_Score
outliers_in_exam_score <- student_data[student_data$Exam_Score > 100,]
outliers_in_exam_score
# Removing outliers
student_data <- subset(student_data, Exam_Score <= 100)

We can see that only 1 student got exam score of 101 which is an outlier. We will remove this row from the dataset.

# Remove outliers
student_data <- subset(student_data, Exam_Score <= 100)

Distribution of Final Exam Scores

Distribution of Final Exam Scores (Without Considering Other Factors)

Here we will explore the distribution of final exam scores among students with without considering other factors. To find our the distribution of final exam scores, we first need to sample the data and plot a histogram.

# Sample the data
set.seed(123)
exam_score_sample <- student_data$Exam_Score[sample(nrow(student_data), round(nrow(student_data)*sample_fraction))]

# Plot histogram
hist(exam_score_sample, main = "Distribution of Final Exam Scores", xlab = "Final Exam Score", col = "skyblue", border = "black")

From the histogram, we can see that the distribution of final exam scores is positively skewed, with most students scoring between 60 and 75. There are a few students who scored below 60 and a few outliers who scored above 80. We will now create a boxplot to visualize the distribution further.

# Boxplot of final exam scores
boxplot(exam_score_sample, main = "Boxplot of Final Exam Scores", col = "skyblue", border = "black")

The boxplot shows the distribution of final exam scores, with the median score around 70. There are a few outliers above 80, indicating that some students performed exceptionally well. We will now use numerical methods to confirm the normality of the distribution.

# Shapiro-Wilk test for normality
shapiro.test(exam_score_sample)

    Shapiro-Wilk normality test

data:  exam_score_sample
W = 0.90062, p-value < 2.2e-16

The Shapiro-Wilk test confirms that the distribution of final exam scores is not normal, with a p-value less than 0.05.

Distribution of Final Exam Scores (Parental_Involvement Category)

Next, we explore the distribution of final exam scores based on parental involvement levels. We will create a boxplot to compare the scores of students with different levels of parental involvement.

# Sample the data
high_parental_involvement_exam_score <- student_data$Exam_Score[student_data$Parental_Involvement == "High"][sample(sum(student_data$Parental_Involvement == "High"), round(sum(student_data$Parental_Involvement == "High")*sample_fraction))]
medium_parental_involvement_exam_score <- student_data$Exam_Score[student_data$Parental_Involvement == "Medium"][sample(sum(student_data$Parental_Involvement == "Medium"), round(sum(student_data$Parental_Involvement == "Medium")*sample_fraction))]
low_parental_involvement_exam_score <- student_data$Exam_Score[student_data$Parental_Involvement == "Low"][sample(sum(student_data$Parental_Involvement == "Low"), round(sum(student_data$Parental_Involvement == "Low")*sample_fraction))]

# Histogram of final exam scores by parental involvement
par(mfrow = c(1, 3))
hist(high_parental_involvement_exam_score, main = "High Parental Involvement", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_parental_involvement_exam_score, main = "Medium Parental Involvement", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(low_parental_involvement_exam_score, main = "Low Parental Involvement", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • High Parental Involvement: The distribution is positively skewed, with most scores between 60 and 80. There are a few outliers above 80, indicating exceptional performance.
  • Medium Parental Involvement: The distribution is similar to high parental involvement, with most scores between 60 and 80. There are a few outliers above 80, indicating exceptional performance.
  • Low Parental Involvement: The distribution appears to be more spread out compared to high and medium parental involvement, with scores ranging from 55 to 75. There are a few outliers above 80, indicating exceptional performance.
# Shapiro-Wilk test for normality
shapiro.test(high_parental_involvement_exam_score)

    Shapiro-Wilk normality test

data:  high_parental_involvement_exam_score
W = 0.93225, p-value = 4.266e-15
shapiro.test(medium_parental_involvement_exam_score)

    Shapiro-Wilk normality test

data:  medium_parental_involvement_exam_score
W = 0.92485, p-value < 2.2e-16
shapiro.test(low_parental_involvement_exam_score)

    Shapiro-Wilk normality test

data:  low_parental_involvement_exam_score
W = 0.971, p-value = 5.719e-07

The Shapiro-Wilk test confirms that the distributions of final exam scores for all students with of parental involvement are not normal, with p-values less than 0.05.

Now we take it a step further by checking whether the distribution of final exam scores is different based on parental involvement levels using Kruskal-Wallis test.

# Summary statistics for final exam scores by parental involvement
summary(high_parental_involvement_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   66.00   68.00   68.04   70.00   99.00 
summary(medium_parental_involvement_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  55.00   65.00   67.00   67.07   69.00   97.00 
summary(low_parental_involvement_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  56.00   64.00   66.00   66.22   68.00   84.00 
# Kruskal-Wallis test for final exam scores by parental involvement
kruskal.test(Exam_Score ~ Parental_Involvement, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Parental_Involvement
Kruskal-Wallis chi-squared = 187.95, df = 2, p-value < 2.2e-16

The Kruskal-Wallis test shows that there is significant difference in the final exam scores based on parental involvement levels, with a p-value less than 0.05. This indicates that parental involvement has a significant impact on the final exam scores. From the summary statistics, we can see that students with high parental involvement have higher average exam scores, followed by students with medium parental involvement, and students with low parental involvement have the lowest average exam scores.

Distribution of Final Exam Scores (Access_to_Resources Category)

Next, we explore the distribution of final exam scores based on access to resources. We will create a boxplot to compare the scores of students with different levels of access to resources.

# Sample the data
high_access_to_resources_exam_score <- student_data$Exam_Score[student_data$Access_to_Resources == "High"][sample(sum(student_data$Access_to_Resources == "High"), round(sum(student_data$Access_to_Resources == "High")*sample_fraction))]
medium_access_to_resources_exam_score <- student_data$Exam_Score[student_data$Access_to_Resources == "Medium"][sample(sum(student_data$Access_to_Resources == "Medium"), round(sum(student_data$Access_to_Resources == "Medium")*sample_fraction))]
low_access_to_resources_exam_score <- student_data$Exam_Score[student_data$Access_to_Resources == "Low"][sample(sum(student_data$Access_to_Resources == "Low"), round(sum(student_data$Access_to_Resources == "Low")*sample_fraction))]

# Histogram of final exam scores by access to resources
par(mfrow = c(1, 3))
hist(high_access_to_resources_exam_score, main = "High Access to Resources", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_access_to_resources_exam_score, main = "Medium Access to Resources", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(low_access_to_resources_exam_score, main = "Low Access to Resources", xlab = "Final Exam Score", col = "skyblue", border = "black")

plot(density(low_access_to_resources_exam_score), main = "Low Access to Resources", xlab = "Final Exam Score", col = "skyblue")
plot(density(medium_access_to_resources_exam_score), main = "Medium Access to Resources", xlab = "Final Exam Score", col = "skyblue")
plot(density(high_access_to_resources_exam_score), main = "High Access to Resources", xlab = "Final Exam Score", col = "skyblue")

  • High Access to Resources: The distribution is positively skewed, with most scores between 60 and 80. There are a few outliers above 80, indicating exceptional performance.
  • Medium Access to Resources: The distribution is similar to high access to resources, with most scores between 60 and 80. There are a few outliers above 80, indicating exceptional performance.
  • Low Access to Resources: The distribution appears to be more spread out compared to high and medium access to resources, with scores ranging from 55 to 75. There are appears to be small tail of students scoring higher.
# Shapiro-Wilk test for normality
shapiro.test(high_access_to_resources_exam_score)

    Shapiro-Wilk normality test

data:  high_access_to_resources_exam_score
W = 0.93853, p-value = 1.369e-14
shapiro.test(medium_access_to_resources_exam_score)

    Shapiro-Wilk normality test

data:  medium_access_to_resources_exam_score
W = 0.91128, p-value < 2.2e-16
shapiro.test(low_access_to_resources_exam_score)

    Shapiro-Wilk normality test

data:  low_access_to_resources_exam_score
W = 0.90969, p-value = 2.501e-14

The Shapiro-Wilk test shows that the distributions of final exam scores for students with high, medium, and low access to resources are not normal, with p-values less than 0.05.

Next, we will use Kruskal-Wallis test to check whether the distribution of final exam scores is different based on access to resources.

# Summary statistics for final exam scores by access to resources
summary(high_access_to_resources_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   68.00   67.85   70.00   95.00 
summary(medium_access_to_resources_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.07   69.00   96.00 
summary(low_access_to_resources_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  55.00   64.00   66.00   66.16   68.00   89.00 
# Kruskal-Wallis test for final exam scores by access to resources
kruskal.test(Exam_Score ~ Access_to_Resources, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Access_to_Resources
Kruskal-Wallis chi-squared = 220.61, df = 2, p-value < 2.2e-16

The Kruskal-Wallis test shows that there is a significant difference in the final exam scores based on access to resources, with a p-value less than 0.05. This indicates that access to resources has a significant impact on the final exam scores. From the summary statistics, we can see that students with high access to resources have higher average exam scores, followed by students with medium access to resources, and students with low access to resources have the lowest average exam scores.

Distribution of Final Exam Scores (Extracurricular_Activities Category)

Next, we explore the distribution of final exam scores based on participation in extracurricular activities. We will create a boxplot to compare the scores of students who participate in extracurricular activities and those who do not.

# Sample the data
participate_extracurricular_exam_score <- student_data$Exam_Score[student_data$Extracurricular_Activities == "Yes"][sample(sum(student_data$Extracurricular_Activities == "Yes"), round(sum(student_data$Extracurricular_Activities == "Yes")*sample_fraction))]
do_not_participate_extracurricular_exam_score <- student_data$Exam_Score[student_data$Extracurricular_Activities == "No"][sample(sum(student_data$Extracurricular_Activities == "No"), round(sum(student_data$Extracurricular_Activities == "No")*sample_fraction))]

# Boxplot of final exam scores by extracurricular activities
boxplot(student_data$Exam_Score ~ student_data$Extracurricular_Activities, main = "Final Exam Scores by Extracurricular Activities", xlab = "Extracurricular Activities", ylab = "Final Exam Score", col = "skyblue", border = "black")

The boxplot shows that students who participate in extracurricular activities tend to have higher final exam scores compared to those who do not. Now we will visualize the distribution of scores for both groups using histograms.

# Histogram of final exam scores by extracurricular activities
par(mfrow = c(1, 2))
hist(participate_extracurricular_exam_score, main = "Extracurricular Activities", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(do_not_participate_extracurricular_exam_score, main = "No Extracurricular Activities", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • Extracurricular Activities: The distribution is positively skewed, with most scores between 60 and 80. There are a few outliers above 80, indicating exceptional performance.
  • No Extracurricular Activities: The distribution is similar to extracurricular activities, with most scores between 60 and 75. There are a few outliers above 80, indicating exceptional performance.
# Shapiro-Wilk test for normality
shapiro.test(participate_extracurricular_exam_score)

    Shapiro-Wilk normality test

data:  participate_extracurricular_exam_score
W = 0.9258, p-value < 2.2e-16
shapiro.test(do_not_participate_extracurricular_exam_score)

    Shapiro-Wilk normality test

data:  do_not_participate_extracurricular_exam_score
W = 0.95191, p-value = 3.643e-15

The Shapiro-Wilk test confirms that both distributions of final exam scores for students who participate in extracurricular activities and those who do not is not normal, with p-values less than 0.05.

Next, we will use Wilcoxon rank-sum test to check whether the distribution of final exam scores is different based on participation in extracurricular activities.

# Summary statistics for final exam scores by extracurricular activities
summary(participate_extracurricular_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  57.00   65.00   67.00   67.36   70.00   99.00 
summary(do_not_participate_extracurricular_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
     58      65      67      67      69      94 
# Wilcoxon rank-sum test for final exam scores by extracurricular activities
wilcox.test(participate_extracurricular_exam_score, do_not_participate_extracurricular_exam_score)

    Wilcoxon rank sum test with continuity correction

data:  participate_extracurricular_exam_score and do_not_participate_extracurricular_exam_score
W = 459999, p-value = 0.09419
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank-sum test shows that there is no significant difference in the final exam scores based on participation in extracurricular activities, with a p-value greater than 0.05. This indicates that participation in extracurricular activities does not have a significant impact on the final exam scores.

Distribution of Final Exam Scores (Motivation_Level Category)

Next we explore the distribution of final exam scores based on motivation levels. We will create a histogram to compare the scores of students with different motivation levels.

# Smaple Data
high_motivation_exam_score <- student_data$Exam_Score[student_data$Motivation_Level == "High"][sample(sum(student_data$Motivation_Level == "High"), round(sum(student_data$Motivation_Level == "High")*sample_fraction))]
medium_motivation_exam_score <- student_data$Exam_Score[student_data$Motivation_Level == "Medium"][sample(sum(student_data$Motivation_Level == "Medium"), round(sum(student_data$Motivation_Level == "Medium")*sample_fraction))]
low_motivation_exam_score <- student_data$Exam_Score[student_data$Motivation_Level == "Low"][sample(sum(student_data$Motivation_Level == "Low"), round(sum(student_data$Motivation_Level == "Low")*sample_fraction))]

# Histogram of final exam scores by motivation level
par(mfrow = c(1, 3))
hist(high_motivation_exam_score, main = "High Motivation Level", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_motivation_exam_score, main = "Medium Motivation Level", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(low_motivation_exam_score, main = "Low Motivation Level", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • High Motivation Level: Exam scores are mostly concentrated between 60 and 75, indicating that students with high motivation consistently perform well. The peak frequency occurs at the middle of this range.
  • Medium Motivation Level: Scores are also clustered between 60 and 80, but with slightly less variability compared to the high-motivation group. There appears to be a small tail of students scoring higher.
  • Low Motivation Level: Scores are less widely spread between 60 and 75, with some outliers scoring much higher.
# Shapiro-Wilk test for normality
shapiro.test(high_motivation_exam_score)

    Shapiro-Wilk normality test

data:  high_motivation_exam_score
W = 0.98159, p-value = 8.452e-05
shapiro.test(medium_motivation_exam_score)

    Shapiro-Wilk normality test

data:  medium_motivation_exam_score
W = 0.93831, p-value < 2.2e-16
shapiro.test(low_motivation_exam_score)

    Shapiro-Wilk normality test

data:  low_motivation_exam_score
W = 0.88117, p-value < 2.2e-16

All tests show that the distribution of final exam scores for students with high, medium, and low motivation levels is not normal, with p-values less than 0.05.

Now we use Kruskal-Wallis test to check whether the distribution of final exam scores is different based on motivation levels.

# Summary statistics for final exam scores by motivation level
summary(high_motivation_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  57.00   65.00   68.00   67.74   70.00   85.00 
summary(medium_motivation_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.35   69.00   99.00 
summary(low_motivation_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  57.00   64.00   67.00   66.76   69.00   95.00 
# Kruskal-Wallis test for final exam scores by motivation level
kruskal.test(Exam_Score ~ Motivation_Level, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Motivation_Level
Kruskal-Wallis chi-squared = 58.359, df = 2, p-value = 2.125e-13

The Kruskal-Wallis test shows that there is a significant difference in the final exam scores based on motivation levels, with a p-value less than 0.05. This indicates that motivation levels have a significant impact on the final exam scores. From the summary statistics, we can see that students with high motivation have higher average exam scores, followed by students with medium motivation, and students with low motivation have the lowest average exam scores.

Distribution of Final Exam Scores (Internet_Access Category)

Next, we explore the distribution of final exam scores based on internet access. We will create a boxplot to compare the scores of students with and without internet access.

# Sample the data
internet_access_exam_score <- student_data$Exam_Score[student_data$Internet_Access == "Yes"][sample(sum(student_data$Internet_Access == "Yes"), round(sum(student_data$Internet_Access == "Yes")*sample_fraction))]
no_internet_access_exam_score <- student_data$Exam_Score[student_data$Internet_Access == "No"][sample(sum(student_data$Internet_Access == "No"), round(sum(student_data$Internet_Access == "No")*sample_fraction))]

# Histogram of final exam scores by internet access
par(mfrow = c(1, 2))
hist(internet_access_exam_score, main = "Internet Access", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(no_internet_access_exam_score, main = "No Internet Access", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • Internet Access: The distribution appears positively skewed, with most scores clustered between 60 and 80. The mode or most frequent score seems to fall around 65-70. There appears to be few outliers scoring above 75.
  • No Internet Access: This distribution is slightly skewed, with scores primarily clustered around 60 and extending toward 75. There are some outliers beyond 75. The highest frequency occurs around 65. Scores are more widely distributed compared to the Internet Access group.
# Shapiro-Wilk test for normality
shapiro.test(internet_access_exam_score)

    Shapiro-Wilk normality test

data:  internet_access_exam_score
W = 0.92648, p-value < 2.2e-16
shapiro.test(no_internet_access_exam_score)

    Shapiro-Wilk normality test

data:  no_internet_access_exam_score
W = 0.86672, p-value = 4.177e-10

The Shapiro-Wilk test confirms that the distribution of final exam scores for students with and without internet access is not normal, with a p-value less than 0.05.

Next, we use Wilcoxon rank-sum test to check whether the distribution of final exam scores is different based on internet access.

# Summary statistics for final exam scores by internet access
summary(internet_access_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  57.00   65.00   67.00   67.21   69.00  100.00 
summary(no_internet_access_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   66.94   69.00   92.00 
# Wilcoxon rank-sum test for final exam scores by internet access
wilcox.test(internet_access_exam_score, no_internet_access_exam_score)

    Wilcoxon rank sum test with continuity correction

data:  internet_access_exam_score and no_internet_access_exam_score
W = 134847, p-value = 0.2953
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank-sum test shows that there is no significant difference in the final exam scores based on internet access, with a p-value greater than 0.05. This indicates that internet access does not have a significant impact on the final exam scores.

Distribution of Final Exam Scores (Family_Income Category)

Next, we explore the distribution of final exam scores based on family income levels.

# Sample the data
low_income_exam_score <- student_data$Exam_Score[student_data$Family_Income == "Low"][sample(sum(student_data$Family_Income == "Low"), round(sum(student_data$Family_Income == "Low")*sample_fraction))]
medium_income_exam_score <- student_data$Exam_Score[student_data$Family_Income == "Medium"][sample(sum(student_data$Family_Income == "Medium"), round(sum(student_data$Family_Income == "Medium")*sample_fraction))]
high_income_exam_score <- student_data$Exam_Score[student_data$Family_Income == "High"][sample(sum(student_data$Family_Income == "High"), round(sum(student_data$Family_Income == "High")*sample_fraction))]

# Histogram of final exam scores by family income
par(mfrow = c(1, 3))
hist(low_income_exam_score, main = "Low Family Income", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_income_exam_score, main = "Medium Family Income", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(high_income_exam_score, main = "High Family Income", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • Low Family Income: The distribution is positively skewed, with most scores between 60 and 75. There are a few outliers above 80, indicating exceptional performance.
  • Medium Family Income: The distribution is similar to low family income, with most scores between 60 and 75. There are a few outliers above 80, indicating exceptional performance.
  • High Family Income: The distribution is positively skewed, and it appears to be more spread out compared to low and medium family income, with scores ranging from 55 to 80. There are a few outliers above 80, indicating exceptional performance.
# Shapiro-Wilk test for normality
shapiro.test(low_income_exam_score)

    Shapiro-Wilk normality test

data:  low_income_exam_score
W = 0.9096, p-value < 2.2e-16
shapiro.test(medium_income_exam_score)

    Shapiro-Wilk normality test

data:  medium_income_exam_score
W = 0.87216, p-value < 2.2e-16
shapiro.test(high_income_exam_score)

    Shapiro-Wilk normality test

data:  high_income_exam_score
W = 0.92426, p-value = 1.038e-12

The Shapiro-Wilk test confirms that the distribution of final exam scores for all students is not normal, with a p-value that is less than 0.05.

We now use Kruskal-Wallis test to check whether the distribution of final exam scores is different based on family income levels.

# Summary statistics for final exam scores by family income
summary(high_income_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   65.00   68.00   67.89   70.00   93.00 
summary(medium_income_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.52   70.00   98.00 
summary(low_income_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   64.00   67.00   66.79   69.00   95.00 
# Kruskal-Wallis test for final exam scores by family income
kruskal.test(Exam_Score ~ Family_Income, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Family_Income
Kruskal-Wallis chi-squared = 60.891, df = 2, p-value = 5.994e-14

The Kruskal-Wallis test shows that there is a significant difference in the final exam scores based on family income levels, with a p-value less than 0.05. This indicates that family income has a significant impact on the final exam scores. From the summary statistics, we can see that students with high family income have higher average exam scores, followed by students with medium family income, and students with low family income have the lowest average exam scores.

Distribution of Final Exam Scores (Teacher_Quality Category)

Next, we explore the distribution of final exam scores based on teacher quality levels.

# Sample data
high_teacher_quality_exam_score <- student_data$Exam_Score[student_data$Teacher_Quality == "High"][sample(sum(student_data$Teacher_Quality == "High"), round(sum(student_data$Teacher_Quality == "High")*sample_fraction))]
medium_teacher_quality_exam_score <- student_data$Exam_Score[student_data$Teacher_Quality == "Medium"][sample(sum(student_data$Teacher_Quality == "Medium"), round(sum(student_data$Teacher_Quality == "Medium")*sample_fraction))]
low_teacher_quality_exam_score <- student_data$Exam_Score[student_data$Teacher_Quality == "Low"][sample(sum(student_data$Teacher_Quality == "Low"), round(sum(student_data$Teacher_Quality == "Low")*sample_fraction))]

# Histogram of final exam scores by teacher quality
par(mfrow = c(1, 3))
hist(high_teacher_quality_exam_score, main = "High Teacher Quality", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_teacher_quality_exam_score, main = "Medium Teacher Quality", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(low_teacher_quality_exam_score, main = "Low Teacher Quality", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • High Teacher Quality: The distribution is positively skewed, with most scores between 60 and 75. There are a few outliers above 80, indicating exceptional performance.
  • Medium Teacher Quality: The distribution is similar to high teacher quality, with most scores between 60 and 75. There are a few outliers above 80, indicating exceptional performance.
  • Low Teacher Quality: The distribution is positively skewed, with scores ranging from 55 to 75. There are a few outliers above 80, indicating exceptional performance.
# Shapiro-Wilk test for normality
shapiro.test(high_teacher_quality_exam_score)

    Shapiro-Wilk normality test

data:  high_teacher_quality_exam_score
W = 0.89397, p-value < 2.2e-16
shapiro.test(medium_teacher_quality_exam_score)

    Shapiro-Wilk normality test

data:  medium_teacher_quality_exam_score
W = 0.86722, p-value < 2.2e-16
shapiro.test(low_teacher_quality_exam_score)

    Shapiro-Wilk normality test

data:  low_teacher_quality_exam_score
W = 0.836, p-value = 1.617e-13

The Shapiro-Wilk test confirms that the distribution of final exam scores for all students is not normal, with a p-value less than 0.05.

We now use Kruskal-Wallis test to check whether the distribution of final exam scores is different based on teacher quality levels.

# Summary statistics for final exam scores by teacher quality
summary(high_teacher_quality_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.53   70.00   98.00 
summary(medium_teacher_quality_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  55.00   64.75   67.00   67.07   69.00   99.00 
summary(low_teacher_quality_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  59.00   64.00   67.00   67.27   69.00   94.00 
# Kruskal-Wallis test for final exam scores by teacher quality
kruskal.test(Exam_Score ~ Teacher_Quality, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Teacher_Quality
Kruskal-Wallis chi-squared = 41.657, df = 2, p-value = 9e-10

The Kruskal-Wallis test shows that there is a significant difference in the final exam scores based on teacher quality levels, with a p-value less than 0.05. This indicates that teacher quality has a significant impact on the final exam scores. From the summary statistics, we can see that students with high teacher quality have higher average exam scores, followed by students with low teacher quality, and students with medium teacher quality have the lowest average exam scores.

Distribution of Final Exam Scores (School_Type Category)

Next, we explore the distribution of final exam scores based on school type.

# Sample data
public_school_exam_score <- student_data$Exam_Score[student_data$School_Type == "Public"][sample(sum(student_data$School_Type == "Public"), round(sum(student_data$School_Type == "Public")*sample_fraction))]
private_school_exam_score <- student_data$Exam_Score[student_data$School_Type == "Private"][sample(sum(student_data$School_Type == "Private"), round(sum(student_data$School_Type == "Private")*sample_fraction))]

# Histogram of final exam scores by school type
par(mfrow = c(1, 2))
hist(public_school_exam_score, main = "Public School", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(private_school_exam_score, main = "Private School", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • Public School: The distribution is positively skewed, with most scores between 60 and 75. There are a few outliers above 80, indicating exceptional performance. The mode or most frequent score seems to fall around 65-70.
  • Private School: The distribution is similar to public school, with most scores between 60 and 75. There are a few outliers above 80, indicating exceptional performance. The mode or most frequent score seems to fall around 65-70.
# Shapiro-Wilk test for normality
shapiro.test(public_school_exam_score)

    Shapiro-Wilk normality test

data:  public_school_exam_score
W = 0.9264, p-value < 2.2e-16
shapiro.test(private_school_exam_score)

    Shapiro-Wilk normality test

data:  private_school_exam_score
W = 0.94435, p-value = 5.599e-14

The Shapiro-Wilk test confirms that the distribution of final exam scores for students in public and private schools is not normal, with a p-value less than 0.05.

We now use Wilcoxon rank-sum test to check whether the distribution of final exam scores is different based on school type.

# Summary statistics for final exam scores by school type
summary(public_school_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.15   69.00   94.00 
summary(private_school_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.29   70.00   92.00 
# Wilcoxon rank-sum test for final exam scores by school type
wilcox.test(public_school_exam_score, private_school_exam_score)

    Wilcoxon rank sum test with continuity correction

data:  public_school_exam_score and private_school_exam_score
W = 379198, p-value = 0.443
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank-sum test shows that there is no significant difference in the final exam scores based on school type, with a p-value greater than 0.05. This indicates that school type does not have a significant impact on the final exam scores.

Distribution of Final Exam Scores (Peer_Influence Category)

Next, we explore the distribution of final exam scores based on peer influence levels.

# Sample data
positive_peer_influence_exam_score <- student_data$Exam_Score[student_data$Peer_Influence == "Positive"][sample(sum(student_data$Peer_Influence == "Positive"), round(sum(student_data$Peer_Influence == "Positive")*sample_fraction))]
negative_peer_influence_exam_score <- student_data$Exam_Score[student_data$Peer_Influence == "Negative"][sample(sum(student_data$Peer_Influence == "Negative"), round(sum(student_data$Peer_Influence == "Negative")*sample_fraction))]
neutral_peer_influence_exam_score <- student_data$Exam_Score[student_data$Peer_Influence == "Neutral"][sample(sum(student_data$Peer_Influence == "Neutral"), round(sum(student_data$Peer_Influence == "Neutral")*sample_fraction))]

# Histogram of final exam scores by peer influence
par(mfrow = c(1, 3))
hist(positive_peer_influence_exam_score, main = "High Peer Influence", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(negative_peer_influence_exam_score, main = "Medium Peer Influence", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(neutral_peer_influence_exam_score, main = "Low Peer Influence", xlab = "Final Exam Score", col = "skyblue", border = "black")

The distributions of final exam scores based on peer influence levels appear to be the same across all categories. The scores appears to be concentrated between 60 and 75 for all peer influence levels, with a few outliers scoring above 80.

# Shapiro-Wilk test for normality
shapiro.test(positive_peer_influence_exam_score)

    Shapiro-Wilk normality test

data:  positive_peer_influence_exam_score
W = 0.89153, p-value < 2.2e-16
shapiro.test(negative_peer_influence_exam_score)

    Shapiro-Wilk normality test

data:  negative_peer_influence_exam_score
W = 0.84839, p-value < 2.2e-16
shapiro.test(neutral_peer_influence_exam_score)

    Shapiro-Wilk normality test

data:  neutral_peer_influence_exam_score
W = 0.92226, p-value < 2.2e-16

The Shapiro-Wilk test confirms that the distribution of final exam scores for all students is not normal, with a p-value less than 0.05.

We now use Kruskal-Wallis test to check whether the distribution of final exam scores is different based on peer influence levels.

# Summary statistics for final exam scores by peer influence
summary(positive_peer_influence_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.56   70.00  100.00 
summary(negative_peer_influence_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  55.00   64.00   66.00   66.62   69.00   99.00 
summary(neutral_peer_influence_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.37   69.00   94.00 
# Kruskal-Wallis test for final exam scores by peer influence
kruskal.test(Exam_Score ~ Peer_Influence, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Peer_Influence
Kruskal-Wallis chi-squared = 80.769, df = 2, p-value < 2.2e-16

The Kruskal-Wallis test shows that there is a significant difference in the final exam scores based on peer influence levels, with a p-value less than 0.05. This indicates that peer influence has a significant impact on the final exam scores. From the summary statistics, we can see that students with positive peer influence have higher average exam scores, followed by students with neutral peer influence, and students with negative peer influence have the lowest average exam scores.

Distribution of Final Exam Scores (Learning_Disabilities Category)

Next, we explore the distribution of final exam scores based on learning disabilities.

# Sample data
learning_disabilities_exam_score <- student_data$Exam_Score[student_data$Learning_Disabilities == "Yes"][sample(sum(student_data$Learning_Disabilities == "Yes"), round(sum(student_data$Learning_Disabilities == "Yes")*sample_fraction))]
no_learning_disabilities_exam_score <- student_data$Exam_Score[student_data$Learning_Disabilities == "No"][sample(sum(student_data$Learning_Disabilities == "No"), round(sum(student_data$Learning_Disabilities == "No")*sample_fraction))]

# Histogram of final exam scores by learning disabilities
par(mfrow = c(1, 2))
hist(learning_disabilities_exam_score, main = "Learning Disabilities", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(no_learning_disabilities_exam_score, main = "No Learning Disabilities", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • Learning Disabilities: Scores are narrowly distributed, primarily clustered between 65 and 75, with a sharp peak around the mid-60s. The smaller sample size is reflected in the lower frequencies.
  • No Learning Disabilities: The distribution is broader, with scores ranging from 60 to 85 and a peak around 70. The larger sample size results in higher frequencies.

Students without learning disabilities generally exhibit a slightly wider spread of exam scores, with higher maximum scores compared to those with learning disabilities. The tighter clustering for students with learning disabilities may suggest consistent but slightly lower scores, potentially highlighting the need for targeted academic support.

# Summary statistics for final exam scores by learning disabilities
summary(learning_disabilities_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   63.00   65.00   65.81   68.00   88.00 
summary(no_learning_disabilities_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  55.00   65.00   67.00   67.26   69.00  100.00 
# Wilcoxon rank-sum test for final exam scores by learning disabilities
wilcox.test(learning_disabilities_exam_score, no_learning_disabilities_exam_score)

    Wilcoxon rank sum test with continuity correction

data:  learning_disabilities_exam_score and no_learning_disabilities_exam_score
W = 127605, p-value = 2.971e-09
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank-sum test shows that there is a significant difference in the final exam scores based on learning disabilities, with a p-value less than 0.05. This indicates that learning disabilities have a significant impact on the final exam scores, with students without learning disabilities scoring higher on average. This indicates that students with learning disabilities may require additional support to improve their academic performance.

Distribution of Final Exam Scores(Parental_Education_Level Category)

Next, we explore the distribution of final exam scores based on parental education levels.

# Sample data
high_school_education_exam_score <- student_data$Exam_Score[student_data$Parental_Education_Level == "High School"][sample(sum(student_data$Parental_Education_Level == "High School"), round(sum(student_data$Parental_Education_Level == "High School")*sample_fraction))]
college_education_exam_score <- student_data$Exam_Score[student_data$Parental_Education_Level == "College"][sample(sum(student_data$Parental_Education_Level == "College"), round(sum(student_data$Parental_Education_Level == "College")*sample_fraction))]
postgraduate_education_exam_score <- student_data$Exam_Score[student_data$Parental_Education_Level == "Postgraduate"][sample(sum(student_data$Parental_Education_Level == "Postgraduate"), round(sum(student_data$Parental_Education_Level == "Postgraduate")*sample_fraction))]

# Histogram of final exam scores by parental education level
par(mfrow = c(1, 3))
hist(high_school_education_exam_score, main = "High School Education", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(college_education_exam_score, main = "College Education", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(postgraduate_education_exam_score, main = "Postgraduate Education", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • High School Education: Scores are tightly clustered, mostly between 65** and **75`. The frequency is highest among all three categories, reflecting a larger number of students from this parental education level.
  • College Education: The distribution broadens slightly compared to the High School group. The scores mostly range between 65 and 80, with a slight increase in higher scores (closer to 80). The frequency is moderate.
  • Postgraduate Education: The distribution is the widest, with scores ranging from 60 to 85. The peak frequency occurs around 70, but there are more students scoring above 80 compared to the other groups.

There is a clear trend of higher average scores for students with parents who have higher education levels. The distribution of scores widens as parental education level increases, indicating a positive correlation between parental education and student performance. This trend suggests that students with parents who have higher education levels may have better academic support and resources, leading to improved exam scores.

# Shapiro-Wilk test for normality
shapiro.test(high_school_education_exam_score)

    Shapiro-Wilk normality test

data:  high_school_education_exam_score
W = 0.909, p-value < 2.2e-16
shapiro.test(college_education_exam_score)

    Shapiro-Wilk normality test

data:  college_education_exam_score
W = 0.928, p-value = 4.311e-16
shapiro.test(postgraduate_education_exam_score)

    Shapiro-Wilk normality test

data:  postgraduate_education_exam_score
W = 0.98321, p-value = 0.000193

The Shapiro-Wilk test confirms that the distribution of final exam scores for all students is not normal, with a p-value less than 0.05.

We now use Kruskal-Wallis test to check whether the distribution of final exam scores is different based on parental education levels.

# Summary statistics for final exam scores by parental education level
summary(high_school_education_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   66.87   69.00   99.00 
summary(college_education_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.45   70.00   92.00 
summary(postgraduate_education_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   65.00   67.00   67.69   70.00   80.00 
# Kruskal-Wallis test for final exam scores by parental education level
kruskal.test(Exam_Score ~ Parental_Education_Level, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Parental_Education_Level
Kruskal-Wallis chi-squared = 92.698, df = 2, p-value < 2.2e-16

The Kruskal-Wallis test shows that there is a significant difference in the final exam scores based on parental education levels, with a p-value less than 0.05. This indicates that parental education levels have a significant impact on the final exam scores. From the summary statistics, we can see that students with parents who have postgraduate education have higher average exam scores, followed by students with parents who have college education, and students with parents who have high school education have the lowest average exam scores. This trend suggests that parental education level is a strong predictor of student performance.

Distribution of Final Exam Scores (Distance_from_Home Category)

Next, we explore the distribution of final exam scores based on the distance from home to school.

# Sample data
near_distance_exam_score <- student_data$Exam_Score[student_data$Distance_from_Home == "Near"][sample(sum(student_data$Distance_from_Home == "Near"), round(sum(student_data$Distance_from_Home == "Near")*sample_fraction))]
moderate_distance_exam_score <- student_data$Exam_Score[student_data$Distance_from_Home == "Moderate"][sample(sum(student_data$Distance_from_Home == "Moderate"), round(sum(student_data$Distance_from_Home == "Moderate")*sample_fraction))]
far_distance_exam_score <- student_data$Exam_Score[student_data$Distance_from_Home == "Far"][sample(sum(student_data$Distance_from_Home == "Far"), round(sum(student_data$Distance_from_Home == "Far")*sample_fraction))]

# Histogram of final exam scores by distance from home
par(mfrow = c(1, 3))
hist(near_distance_exam_score, main = "Near Distance", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(moderate_distance_exam_score, main = "Moderate Distance", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(far_distance_exam_score, main = "Far Distance", xlab = "Final Exam Score", col = "skyblue", border = "black")

The distributions of final exam scores based on distance from home to school show a similar pattern across all categories. The scores are clustered between 60 and 75 for all distance levels, with a few outliers scoring above 80. The distribution is slightly wider for students living far from school, indicating a slightly higher variability in scores compared to students living near or at a moderate distance from school.

# Summary statistics for final exam scores by distance from home
summary(near_distance_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   55.0    65.0    67.0    67.4    70.0    98.0 
summary(moderate_distance_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  57.00   65.00   67.00   66.99   69.00   98.00 
summary(far_distance_exam_score)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  58.00   64.00   66.00   66.23   68.00   92.00 
# Kruskal-Wallis test for final exam scores by distance from home
kruskal.test(Exam_Score ~ Distance_from_Home, data = student_data)

    Kruskal-Wallis rank sum test

data:  Exam_Score by Distance_from_Home
Kruskal-Wallis chi-squared = 65.02, df = 2, p-value = 7.606e-15

The Kruskal-Wallis test shows that there is a significant difference in the final exam scores based on distance from home to school, with a p-value less than 0.05. This indicates that distance from home has a significant impact on the final exam scores. From the summary statistics, we can see that students living near to school have higher average exam scores, followed by students living at a moderate distance, and students living far from school have the lowest average exam scores. This trend suggests that students living far from school may have better academic support or resources, leading to improved exam scores.

Summary of Distribution Analysis

In summary, the distribution analysis of final exam scores based on various factors reveals the following insights:

  • Parental Involvement: There is a significant difference in final exam scores based on parental involvement levels, with students having high parental involvement scoring higher on average.
  • Access to Resources: There is a significant difference in final exam scores based on access to resources, with students having high access to resources scoring higher on average.
  • Extracurricular Activities: Participation in extracurricular activities does not have a significant impact on final exam scores.
  • Motivation Level: There is a significant difference in final exam scores based on motivation levels, with students having high motivation scoring higher on average.
  • Internet Access: Internet access does not have a significant impact on final exam scores.
  • Family Income: There is a significant difference in final exam scores based on family income levels, with students from high-income families scoring higher on average.
  • Teacher Quality: There is a significant difference in final exam scores based on teacher quality levels, with students having high teacher quality scoring higher on average.
  • School Type: School type does not have a significant impact on final exam scores.
  • Peer Influence: There is a significant difference in final exam scores based on peer influence levels, with students having positive peer influence scoring higher on average.
  • Learning Disabilities: There is a significant difference in final exam scores based on learning disabilities, with students without learning disabilities scoring higher on average.
  • Parental Education Level: There is a significant difference in final exam scores based on parental education levels, with students having parents with postgraduate education scoring higher on average.
  • Distance from Home: There is a significant difference in final exam scores based on distance from home to school, with students living near to school scoring higher on average

Average number of hours students study per week

Average Number of Hours Students Study per Week (Without Considering Other Factors)

Next, we explore the average number of hours students study per week without considering other factors.

# Sample the data
sample_hours_studied <- student_data$Hours_Studied[sample(nrow(student_data), round(nrow(student_data)*sample_fraction))]
summary(sample_hours_studied)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   19.92   24.00   44.00 

We will now visualize the distribution of study hours using a histogram.

# Histogram of study hours
hist(sample_hours_studied, main = "Distribution of Study Hours", xlab = "Study Hours", col = "skyblue", border = "black")

The distribution of study hours appears to be normal. We will now use numerical methods to confirm the normality of the distribution.

# Shapiro-Wilk test for normality
shapiro.test(sample_hours_studied)

    Shapiro-Wilk normality test

data:  sample_hours_studied
W = 0.99695, p-value = 0.0007824

The p-value is less than 0.05, indicating that the distribution of study hours is not normal.

Average Number of Hours Students Study per Week (Parental_Involvement Category)

Next, we will explore the average number of hours students study per week based on parental involvement levels.

# Sample the data
high_parental_involvement_hrs <- student_data$Hours_Studied[student_data$Parental_Involvement == "High"][sample(sum(student_data$Parental_Involvement == "High"), round(sum(student_data$Parental_Involvement == "High")*sample_fraction))]
medium_parental_involvement_hrs <- student_data$Hours_Studied[student_data$Parental_Involvement == "Medium"][sample(sum(student_data$Parental_Involvement == "Medium"), round(sum(student_data$Parental_Involvement == "Medium")*sample_fraction))]
low_parental_involvement_hrs <- student_data$Hours_Studied[student_data$Parental_Involvement == "Low"][sample(sum(student_data$Parental_Involvement == "Low"), round(sum(student_data$Parental_Involvement == "Low")*sample_fraction))]

# Summary statistics for study hours by parental involvement
summary(high_parental_involvement_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    3.0    16.0    20.0    19.8    24.0    43.0 
summary(medium_parental_involvement_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0    16.0    20.0    20.2    24.0    39.0 
summary(low_parental_involvement_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   17.00   20.00   20.34   24.00   35.00 

The summary statistics of the average number of hours students study per week based on parental involvement levels do not show significant differences. We will now use ANOVA to test for differences in study hours based on parental involvement levels. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by parental involvement
par(mfrow = c(1, 3))
hist(high_parental_involvement_hrs, main = "High Parental Involvement", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_parental_involvement_hrs, main = "Medium Parental Involvement", xlab = "Study Hours", col = "skyblue", border = "black")
hist(low_parental_involvement_hrs, main = "Low Parental Involvement", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_parental_involvement_hrs)

    Shapiro-Wilk normality test

data:  high_parental_involvement_hrs
W = 0.99355, p-value = 0.01867
shapiro.test(medium_parental_involvement_hrs)

    Shapiro-Wilk normality test

data:  medium_parental_involvement_hrs
W = 0.99646, p-value = 0.02686
shapiro.test(low_parental_involvement_hrs)

    Shapiro-Wilk normality test

data:  low_parental_involvement_hrs
W = 0.99349, p-value = 0.09415

Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with high and low parental involvement, but not for students with medium parental involvement. We will now use Kruskal-Wallis test to check whether the distribution of study hours is different based on parental involvement levels.

# Kruskal-Wallis test for study hours by parental involvement
kruskal.test(Hours_Studied ~ Parental_Involvement, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Parental_Involvement
Kruskal-Wallis chi-squared = 1.9182, df = 2, p-value = 0.3832

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on parental involvement levels, with a p-value greater than 0.05. This indicates that parental involvement does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of parental involvement levels.

# Chi-square test for study hours by parental involvement
table_parental_involvement_hours <- table(student_data$Hours_Studied, student_data$Parental_Involvement)
chisq.test(table_parental_involvement_hours)
Warning in chisq.test(table_parental_involvement_hours): Chi-squared
approximation may be incorrect

    Pearson's Chi-squared test

data:  table_parental_involvement_hours
X-squared = 71.421, df = 80, p-value = 0.7424

The Chi-square test shows that study hours are independent of parental involvement levels, with a p-value greater than 0.05. This further confirms that parental involvement does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Access_to_Resources Category)

We now explore the average number of hours students study per week based on access to resources.

# Sample the data
high_access_to_resources_hrs <- student_data$Hours_Studied[student_data$Access_to_Resources == "High"][sample(sum(student_data$Access_to_Resources == "High"), round(sum(student_data$Access_to_Resources == "High")*sample_fraction))]
medium_access_to_resources_hrs <- student_data$Hours_Studied[student_data$Access_to_Resources == "Medium"][sample(sum(student_data$Access_to_Resources == "Medium"), round(sum(student_data$Access_to_Resources == "Medium")*sample_fraction))]
low_access_to_resources_hrs <- student_data$Hours_Studied[student_data$Access_to_Resources == "Low"][sample(sum(student_data$Access_to_Resources == "Low"), round(sum(student_data$Access_to_Resources == "Low")*sample_fraction))]

# Summary statistics for study hours by access to resources
summary(high_access_to_resources_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   4.00   16.00   20.00   20.08   24.00   39.00 
summary(medium_access_to_resources_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   15.00   20.00   19.75   24.00   38.00 
summary(low_access_to_resources_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   17.00   20.00   20.36   24.00   44.00 

The summary statistics of the average number of hours students study per week based on access to resources do not show significant differences. We will now use ANOVA to test for differences in study hours based on access to resources. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by access to resources
par(mfrow = c(1, 3))
hist(high_access_to_resources_hrs, main = "High Access to Resources", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_access_to_resources_hrs, main = "Medium Access to Resources", xlab = "Study Hours", col = "skyblue", border = "black")
hist(low_access_to_resources_hrs, main = "Low Access to Resources", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_access_to_resources_hrs)

    Shapiro-Wilk normality test

data:  high_access_to_resources_hrs
W = 0.9941, p-value = 0.02592
shapiro.test(medium_access_to_resources_hrs)

    Shapiro-Wilk normality test

data:  medium_access_to_resources_hrs
W = 0.99628, p-value = 0.02188
shapiro.test(low_access_to_resources_hrs)

    Shapiro-Wilk normality test

data:  low_access_to_resources_hrs
W = 0.99037, p-value = 0.01329

Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with high and low access to resources, but not for students with medium access to resources. We will now use Kruskal-Wallis test to check whether the distribution of study hours is different based on access to resources levels.

# Kruskal-Wallis test for study hours by access to resources
kruskal.test(Hours_Studied ~ Access_to_Resources, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Access_to_Resources
Kruskal-Wallis chi-squared = 2.4291, df = 2, p-value = 0.2968

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on access to resources levels, with a p-value greater than 0.05. This indicates that access to resources does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of access to resources levels.

# Chi-square test for study hours by access to resources
table_access_to_resources_hours <- table(student_data$Hours_Studied, student_data$Access_to_Resources)
chisq.test(table_access_to_resources_hours)
Warning in chisq.test(table_access_to_resources_hours): Chi-squared
approximation may be incorrect

    Pearson's Chi-squared test

data:  table_access_to_resources_hours
X-squared = 90.295, df = 80, p-value = 0.2023

The Chi-square test shows that study hours are independent of access to resources levels, with a p-value greater than 0.05. This further confirms that access to resources does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Extracurricular_Activities Category)

Next, we explore the average number of hours students study per week based on participation in extracurricular activities.

# Sample the data
participate_extracurricular_hrs <- student_data$Hours_Studied[student_data$Extracurricular_Activities == "Yes"][sample(sum(student_data$Extracurricular_Activities == "Yes"), round(sum(student_data$Extracurricular_Activities == "Yes")*sample_fraction))]
do_not_participate_extracurricular_hrs <- student_data$Hours_Studied[student_data$Extracurricular_Activities == "No"][sample(sum(student_data$Extracurricular_Activities == "No"), round(sum(student_data$Extracurricular_Activities == "No")*sample_fraction))]

# Summary statistics for study hours by extracurricular activities
summary(participate_extracurricular_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1      16      20      20      24      39 
summary(do_not_participate_extracurricular_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   20.16   24.00   39.00 

The summary statistics of the average number of hours students study per week based on participation in extracurricular activities show no significant differences. We will now use t-test to test for differences in study hours based on participation in extracurricular activities. But first, we need to check the assumptions of t-test.

# Histogram of study hours by extracurricular activities
par(mfrow = c(1, 2))
hist(participate_extracurricular_hrs, main = "Extracurricular Activities", xlab = "Study Hours", col = "skyblue", border = "black")
hist(do_not_participate_extracurricular_hrs, main = "No Extracurricular Activities", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(participate_extracurricular_hrs)

    Shapiro-Wilk normality test

data:  participate_extracurricular_hrs
W = 0.99546, p-value = 0.00176
shapiro.test(do_not_participate_extracurricular_hrs)

    Shapiro-Wilk normality test

data:  do_not_participate_extracurricular_hrs
W = 0.9951, p-value = 0.01451

The Shapiro-Wilk test shows that the distribution of study hours is not normal for all students. We will now use Wilcoxon rank-sum test to check whether the distribution of study hours is different based on participation in extracurricular activities.

# Wilcoxon rank-sum test for study hours by extracurricular activities
wilcox.test(participate_extracurricular_hrs, do_not_participate_extracurricular_hrs)

    Wilcoxon rank sum test with continuity correction

data:  participate_extracurricular_hrs and do_not_participate_extracurricular_hrs
W = 436015, p-value = 0.721
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank-sum test shows that there is no significant difference in the average number of hours students study per week based on participation in extracurricular activities, with a p-value greater than 0.05. This indicates that participation in extracurricular activities does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of participation in extracurricular activities.

# Chi-square test for study hours by extracurricular activities
table_extracurricular_activities_hours <- table(student_data$Hours_Studied, student_data$Extracurricular_Activities)
chisq.test(table_extracurricular_activities_hours)
Warning in chisq.test(table_extracurricular_activities_hours): Chi-squared
approximation may be incorrect

    Pearson's Chi-squared test

data:  table_extracurricular_activities_hours
X-squared = 45.098, df = 40, p-value = 0.2672

The Chi-square test shows that study hours are independent of participation in extracurricular activities, with a p-value greater than 0.05. This further confirms that participation in extracurricular activities does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Motivation_Level Category)

Next, we explore the average number of hours students study per week based on motivation levels.

# Sample the data
high_motivation_hrs <- student_data$Hours_Studied[student_data$Motivation_Level == "High"][sample(sum(student_data$Motivation_Level == "High"), round(sum(student_data$Motivation_Level == "High")*sample_fraction))]
medium_motivation_hrs <- student_data$Hours_Studied[student_data$Motivation_Level == "Medium"][sample(sum(student_data$Motivation_Level == "Medium"), round(sum(student_data$Motivation_Level == "Medium")*sample_fraction))]
low_motivation_hrs <- student_data$Hours_Studied[student_data$Motivation_Level == "Low"][sample(sum(student_data$Motivation_Level == "Low"), round(sum(student_data$Motivation_Level == "Low")*sample_fraction))]

# Summary statistics for study hours by motivation level
summary(high_motivation_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   4.00   16.00   20.00   19.57   23.00   38.00 
summary(medium_motivation_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   20.03   24.00   39.00 
summary(low_motivation_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   20.07   24.00   38.00 

The summary statistics of the average number of hours students study per week based on motivation levels show no significant differences. We will now use ANOVA to test for differences in study hours based on motivation levels. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by motivation level
par(mfrow = c(1, 3))
hist(high_motivation_hrs, main = "High Motivation Level", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_motivation_hrs, main = "Medium Motivation Level", xlab = "Study Hours", col = "skyblue", border = "black")
hist(low_motivation_hrs, main = "Low Motivation Level", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_motivation_hrs)

    Shapiro-Wilk normality test

data:  high_motivation_hrs
W = 0.99453, p-value = 0.1897
shapiro.test(medium_motivation_hrs)

    Shapiro-Wilk normality test

data:  medium_motivation_hrs
W = 0.99625, p-value = 0.01957
shapiro.test(low_motivation_hrs)

    Shapiro-Wilk normality test

data:  low_motivation_hrs
W = 0.9952, p-value = 0.08049

Shapiro-Wilk test shows that the distribution of study hours of students with high and medium motivation is not normal, with a p-value less than 0.05. We will now use Kruksal-Wallis test to test for differences in study hours based on motivation levels.

# Kruskal-Wallis test for study hours by motivation level
kruskal.test(Hours_Studied ~ Motivation_Level, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Motivation_Level
Kruskal-Wallis chi-squared = 2.9587, df = 2, p-value = 0.2278

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on motivation levels, with a p-value greater than 0.05. This indicates that motivation levels do not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of motivation levels.

# Chi-square test for study hours by motivation level
table_motivation_level_hours <- table(student_data$Hours_Studied, student_data$Motivation_Level)
chisq.test(table_motivation_level_hours)
Warning in chisq.test(table_motivation_level_hours): Chi-squared approximation
may be incorrect

    Pearson's Chi-squared test

data:  table_motivation_level_hours
X-squared = 64.074, df = 80, p-value = 0.9032

The Chi-square test shows that study hours are independent of motivation levels, with a p-value greater than 0.05. This further confirms that motivation levels do not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Internet Access Category)

Next, we explore the average number of hours students study per week based on internet access.

# Sample the data
internet_access_hrs <- student_data$Hours_Studied[student_data$Internet_Access == "Yes"][sample(sum(student_data$Internet_Access == "Yes"), round(sum(student_data$Internet_Access == "Yes")*sample_fraction))]
no_internet_access_hrs <- student_data$Hours_Studied[student_data$Internet_Access == "No"][sample(sum(student_data$Internet_Access == "No"), round(sum(student_data$Internet_Access == "No")*sample_fraction))]

# Summary statistics for study hours by internet access
summary(internet_access_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.99   24.00   43.00 
summary(no_internet_access_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   5.00   15.00   20.00   19.46   24.00   33.00 

The summary statistics of the average number of hours students study per week based on internet access show no significant differences. We will now use t-test to test for differences in study hours based on internet access. But first, we need to check the assumptions of t-test.

# Histogram of study hours by internet access
par(mfrow = c(1, 2))
hist(internet_access_hrs, main = "Internet Access", xlab = "Study Hours", col = "skyblue", border = "black")
hist(no_internet_access_hrs, main = "No Internet Access", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(internet_access_hrs)

    Shapiro-Wilk normality test

data:  internet_access_hrs
W = 0.9965, p-value = 0.0004448
shapiro.test(no_internet_access_hrs)

    Shapiro-Wilk normality test

data:  no_internet_access_hrs
W = 0.98639, p-value = 0.165

Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with no internet access, but not for students with internet access. We will now use Wilcoxon rank-sum test to check whether the distribution of study hours is different based on internet access.

# Wilcoxon rank-sum test for study hours by internet access
wilcox.test(internet_access_hrs, no_internet_access_hrs)

    Wilcoxon rank sum test with continuity correction

data:  internet_access_hrs and no_internet_access_hrs
W = 134283, p-value = 0.3393
alternative hypothesis: true location shift is not equal to 0

The p-value is less than 0.05, indicating that there is a significant difference in the average number of hours students study per week based on internet access. This suggests that internet access has a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of internet access.

# Chi-square test for study hours by internet access
table_internet_access_hours <- table(student_data$Hours_Studied, student_data$Internet_Access)
chisq.test(table_internet_access_hours)
Warning in chisq.test(table_internet_access_hours): Chi-squared approximation
may be incorrect

    Pearson's Chi-squared test

data:  table_internet_access_hours
X-squared = 26.565, df = 40, p-value = 0.9491

The Chi-square test shows that study hours are independent of internet access, with a p-value greater than 0.05.

Average Number of Hours Students Study per Week (Family Income Category)

Next, we explore the average number of hours students study per week based on family income levels.

# Sample the data
low_family_income_hrs <- student_data$Hours_Studied[student_data$Family_Income == "Low"][sample(sum(student_data$Family_Income == "Low"), round(sum(student_data$Family_Income == "Low")*sample_fraction))]
medium_family_income_hrs <- student_data$Hours_Studied[student_data$Family_Income == "Medium"][sample(sum(student_data$Family_Income == "Medium"), round(sum(student_data$Family_Income == "Medium")*sample_fraction))]
high_family_income_hrs <- student_data$Hours_Studied[student_data$Family_Income == "High"][sample(sum(student_data$Family_Income == "High"), round(sum(student_data$Family_Income == "High")*sample_fraction))]

# Summary statistics for study hours by family income
summary(low_family_income_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.69   24.00   38.00 
summary(medium_family_income_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.22   24.00   43.00 
summary(high_family_income_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   17.00   20.00   20.29   24.00   39.00 

The summary statistics of the average number of hours students study per week based on family income levels show no significant differences. We will now use ANOVA to test for differences in study hours based on family income levels. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by family income
par(mfrow = c(1, 3))
hist(low_family_income_hrs, main = "Low Family Income", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_family_income_hrs, main = "Medium Family Income", xlab = "Study Hours", col = "skyblue", border = "black")
hist(high_family_income_hrs, main = "High Family Income", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(low_family_income_hrs)

    Shapiro-Wilk normality test

data:  low_family_income_hrs
W = 0.99676, p-value = 0.1187
shapiro.test(medium_family_income_hrs)

    Shapiro-Wilk normality test

data:  medium_family_income_hrs
W = 0.99622, p-value = 0.06124
shapiro.test(high_family_income_hrs)

    Shapiro-Wilk normality test

data:  high_family_income_hrs
W = 0.99571, p-value = 0.4118

The Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with low and high family income, but not for students with medium family income. We will now use Kruskal-Wallis test to check whether the distribution of study hours is different based on family income levels.

# Kruskal-Wallis test for study hours by family income
kruskal.test(Hours_Studied ~ Family_Income, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Family_Income
Kruskal-Wallis chi-squared = 1.0581, df = 2, p-value = 0.5892

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on family income levels, with a p-value greater than 0.05. This indicates that family income does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of family income levels.

# Chi-square test for study hours by family income
table_family_income_hours <- table(student_data$Hours_Studied, student_data$Family_Income)
chisq.test(table_family_income_hours)
Warning in chisq.test(table_family_income_hours): Chi-squared approximation may
be incorrect

    Pearson's Chi-squared test

data:  table_family_income_hours
X-squared = 74.705, df = 80, p-value = 0.6462

The Chi-square test shows that study hours are independent of family income levels, with a p-value greater than 0.05. This further confirms that family income does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Teacher Quality Category)

Next, we explore the average number of hours students study per week based on teacher quality levels.

# Sample the data
low_teacher_quality_hrs <- student_data$Hours_Studied[student_data$Teacher_Quality == "Low"][sample(sum(student_data$Teacher_Quality == "Low"), round(sum(student_data$Teacher_Quality == "Low")*sample_fraction))]
medium_teacher_quality_hrs <- student_data$Hours_Studied[student_data$Teacher_Quality == "Medium"][sample(sum(student_data$Teacher_Quality == "Medium"), round(sum(student_data$Teacher_Quality == "Medium")*sample_fraction))]
high_teacher_quality_hrs <- student_data$Hours_Studied[student_data$Teacher_Quality == "High"][sample(sum(student_data$Teacher_Quality == "High"), round(sum(student_data$Teacher_Quality == "High")*sample_fraction))]

# Summary statistics for study hours by teacher quality
summary(low_teacher_quality_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   6.00   16.00   19.00   19.25   23.00   32.00 
summary(medium_teacher_quality_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.94   24.00   39.00 
summary(high_teacher_quality_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   19.84   24.00   37.00 

The summary statistics of the average number of hours students study per week based on teacher quality levels show no significant differences. We will now use ANOVA to test for differences in study hours based on teacher quality levels. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by teacher quality
par(mfrow = c(1, 3))
hist(low_teacher_quality_hrs, main = "Low Teacher Quality", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_teacher_quality_hrs, main = "Medium Teacher Quality", xlab = "Study Hours", col = "skyblue", border = "black")
hist(high_teacher_quality_hrs, main = "High Teacher Quality", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(low_teacher_quality_hrs)

    Shapiro-Wilk normality test

data:  low_teacher_quality_hrs
W = 0.99002, p-value = 0.1969
shapiro.test(medium_teacher_quality_hrs)

    Shapiro-Wilk normality test

data:  medium_teacher_quality_hrs
W = 0.99628, p-value = 0.007453
shapiro.test(high_teacher_quality_hrs)

    Shapiro-Wilk normality test

data:  high_teacher_quality_hrs
W = 0.99565, p-value = 0.1131

The Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with low and high teacher quality, but not for students with medium teacher quality. We will now use Kruksal-Wallis test to test for differences in study hours based on teacher quality levels.

# Kruskal-Wallis test for study hours by teacher quality
kruskal.test(Hours_Studied ~ Teacher_Quality, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Teacher_Quality
Kruskal-Wallis chi-squared = 0.30482, df = 2, p-value = 0.8586

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on teacher quality levels, with a p-value greater than 0.05. This indicates that teacher quality does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of teacher quality levels.

# Chi-square test for study hours by teacher quality
table_teacher_quality_hours <- table(student_data$Hours_Studied, student_data$Teacher_Quality)
chisq.test(table_teacher_quality_hours)
Warning in chisq.test(table_teacher_quality_hours): Chi-squared approximation
may be incorrect

    Pearson's Chi-squared test

data:  table_teacher_quality_hours
X-squared = 73.317, df = 80, p-value = 0.6882

The Chi-square test shows that study hours are independent of teacher quality levels, with a p-value greater than 0.05. This further confirms that teacher quality does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (School Type Category)

Next, we explore the average number of hours students study per week based on a school type.

# Sample the data
public_school_hrs <- student_data$Hours_Studied[student_data$School_Type == "Public"][sample(sum(student_data$School_Type == "Public"), round(sum(student_data$School_Type == "Public")*sample_fraction))]
private_school_hrs <- student_data$Hours_Studied[student_data$School_Type == "Private"][sample(sum(student_data$School_Type == "Private"), round(sum(student_data$School_Type == "Private")*sample_fraction))]

# Summary statistics for study hours by school type
summary(public_school_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.96   24.00   43.00 
summary(private_school_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.06   24.00   39.00 

The summary statistics of the average number of hours students study per week based on school type show no significant differences. We will now use t-test to test for differences in study hours based on school type. But first, we need to check the assumptions of t-test.

# Histogram of study hours by school type
par(mfrow = c(1, 2))
hist(public_school_hrs, main = "Public School", xlab = "Study Hours", col = "skyblue", border = "black")
hist(private_school_hrs, main = "Private School", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(public_school_hrs)

    Shapiro-Wilk normality test

data:  public_school_hrs
W = 0.99666, p-value = 0.005918
shapiro.test(private_school_hrs)

    Shapiro-Wilk normality test

data:  private_school_hrs
W = 0.99264, p-value = 0.005719

The Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students from private schools. We will now use Wilcoxon rank-sum test to check whether the distribution of study hours is different based on school type.

# Wilcoxon rank-sum test for study hours by school type
wilcox.test(public_school_hrs, private_school_hrs)

    Wilcoxon rank sum test with continuity correction

data:  public_school_hrs and private_school_hrs
W = 381940, p-value = 0.6044
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank-sum test shows that there is no significant difference in the average number of hours students study per week based on school type, with a p-value greater than 0.05. This indicates that school type does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of school type.

# Chi-square test for study hours by school type
table_school_type_hours <- table(student_data$Hours_Studied, student_data$School_Type)
chisq.test(table_school_type_hours)
Warning in chisq.test(table_school_type_hours): Chi-squared approximation may
be incorrect

    Pearson's Chi-squared test

data:  table_school_type_hours
X-squared = 29.639, df = 40, p-value = 0.885

The Chi-square test shows that study hours are independent of school type, with a p-value greater than 0.05. This further confirms that school type does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Peer Influence Category)

Next, we explore the average number of hours students study per week based on peer influence levels.

# Sample the data
positive_peer_influence_hrs <- student_data$Hours_Studied[student_data$Peer_Influence == "Positive"][sample(sum(student_data$Peer_Influence == "Positive"), round(sum(student_data$Peer_Influence == "Positive")*sample_fraction))]
negative_peer_influence_hrs <- student_data$Hours_Studied[student_data$Peer_Influence == "Negative"][sample(sum(student_data$Peer_Influence == "Negative"), round(sum(student_data$Peer_Influence == "Negative")*sample_fraction))]
neutral_peer_influence_hrs <- student_data$Hours_Studied[student_data$Peer_Influence == "Neutral"][sample(sum(student_data$Peer_Influence == "Neutral"), round(sum(student_data$Peer_Influence == "Neutral")*sample_fraction))]

# Summary statistics for study hours by peer influence
summary(positive_peer_influence_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0    16.0    20.0    20.1    24.0    43.0 
summary(negative_peer_influence_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   4.00   15.50   19.00   19.55   23.00   38.00 
summary(neutral_peer_influence_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   19.84   24.00   35.00 

The summary statistics of the average number of hours students study per week based on peer influence levels show no significant differences. We will now use ANOVA to test for differences in study hours based on peer influence levels. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by peer influence
par(mfrow = c(1, 3))
hist(positive_peer_influence_hrs, main = "Positive Peer Influence", xlab = "Study Hours", col = "skyblue", border = "black")
hist(negative_peer_influence_hrs, main = "Negative Peer Influence", xlab = "Study Hours", col = "skyblue", border = "black")
hist(neutral_peer_influence_hrs, main = "Neutral Peer Influence", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(positive_peer_influence_hrs)

    Shapiro-Wilk normality test

data:  positive_peer_influence_hrs
W = 0.99609, p-value = 0.05297
shapiro.test(negative_peer_influence_hrs)

    Shapiro-Wilk normality test

data:  negative_peer_influence_hrs
W = 0.98604, p-value = 0.0006924
shapiro.test(neutral_peer_influence_hrs)

    Shapiro-Wilk normality test

data:  neutral_peer_influence_hrs
W = 0.99539, p-value = 0.0246

The Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with negative peer influence, but not for students with neutral and positive peer influence. We will now use Kruskal-Wallis test to test for differences in study hours based on peer influence levels.

# Kruskal-Wallis test for study hours by peer influence
kruskal.test(Hours_Studied ~ Peer_Influence, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Peer_Influence
Kruskal-Wallis chi-squared = 0.36274, df = 2, p-value = 0.8341

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on peer influence levels, with a p-value greater than 0.05. This indicates that peer influence does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of peer influence levels.

# Chi-square test for study hours by peer influence
table_peer_influence_hours <- table(student_data$Hours_Studied, student_data$Peer_Influence)
chisq.test(table_peer_influence_hours)
Warning in chisq.test(table_peer_influence_hours): Chi-squared approximation
may be incorrect

    Pearson's Chi-squared test

data:  table_peer_influence_hours
X-squared = 77.091, df = 80, p-value = 0.5714

The Chi-square test shows that study hours are independent of peer influence levels, with a p-value greater than 0.05. This further confirms that peer influence does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Learning Disability Category)

Next, we explore the average number of hours students study per week based on learning disability.

# Sample the data
learning_disabilities_hrs <- student_data$Hours_Studied[student_data$Learning_Disabilities == "Yes"][sample(sum(student_data$Learning_Disabilities == "Yes"), round(sum(student_data$Learning_Disabilities == "Yes")*sample_fraction))]
no_learning_disabilities_hrs <- student_data$Hours_Studied[student_data$Learning_Disabilities == "No"][sample(sum(student_data$Learning_Disabilities == "No"), round(sum(student_data$Learning_Disabilities == "No")*sample_fraction))]

# Summary statistics for study hours by learning disability
summary(learning_disabilities_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   7.00   15.00   20.00   19.68   23.00   35.00 
summary(no_learning_disabilities_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   20.09   24.00   39.00 

The summary statistics of the average number of hours students study per week based on learning disability show no significant differences. We will now use t-test to test for differences in study hours based on learning disability. But first, we need to check the assumptions of t-test.

# Histogram of study hours by learning disability
par(mfrow = c(1, 2))
hist(learning_disabilities_hrs, main = "Learning Disabilities", xlab = "Study Hours", col = "skyblue", border = "black")
hist(no_learning_disabilities_hrs, main = "No Learning Disabilities", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(learning_disabilities_hrs)

    Shapiro-Wilk normality test

data:  learning_disabilities_hrs
W = 0.98723, p-value = 0.06905
shapiro.test(no_learning_disabilities_hrs)

    Shapiro-Wilk normality test

data:  no_learning_disabilities_hrs
W = 0.99644, p-value = 0.000504

The Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with learning disabilities, with a p-value greater than 0.05. However, the distribution for students without learning disabilities is slightly skewed, with a p-value less than 0.05. We will now use wilcoxon rank sum test to test for differences in study hours based on learning disability.

# Wilcoxon rank sum test for study hours by learning disability
wilcox.test(learning_disabilities_hrs, no_learning_disabilities_hrs)

    Wilcoxon rank sum test with continuity correction

data:  learning_disabilities_hrs and no_learning_disabilities_hrs
W = 162148, p-value = 0.2151
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank sum test shows that there is no significant difference in the average number of hours students study per week based on learning disability, with a p-value greater than 0.05. This indicates that learning disabilities do not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of learning disability.

# Chi-square test for study hours by learning disability
table_learning_disabilities_hours <- table(student_data$Hours_Studied, student_data$Learning_Disabilities)
chisq.test(table_learning_disabilities_hours)
Warning in chisq.test(table_learning_disabilities_hours): Chi-squared
approximation may be incorrect

    Pearson's Chi-squared test

data:  table_learning_disabilities_hours
X-squared = 35.224, df = 40, p-value = 0.6849

The Chi-square test shows that study hours are independent of learning disabilities, with a p-value greater than 0.05. This further confirms that learning disabilities do not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Parental Education Level Category)

Next, we explore the average number of hours students study per week based on parental education levels.

# Sample the data
high_school_education_hrs <- student_data$Hours_Studied[student_data$Parental_Education_Level == "High School"][sample(sum(student_data$Parental_Education_Level == "High School"), round(sum(student_data$Parental_Education_Level == "High School")*sample_fraction))]
college_education_hrs <- student_data$Hours_Studied[student_data$Parental_Education_Level == "College"][sample(sum(student_data$Parental_Education_Level == "College"), round(sum(student_data$Parental_Education_Level == "College")*sample_fraction))]
postgraduate_education_hrs <- student_data$Hours_Studied[student_data$Parental_Education_Level == "Postgraduate"][sample(sum(student_data$Parental_Education_Level == "Postgraduate"), round(sum(student_data$Parental_Education_Level == "Postgraduate")*sample_fraction))]

# Summary statistics for study hours by parental education level
summary(high_school_education_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.87   24.00   39.00 
summary(college_education_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   20.26   24.00   39.00 
summary(postgraduate_education_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   20.27   25.00   39.00 

The summary statistics of the average number of hours students study per week based on parental education levels show no significant differences. We will now use ANOVA to test for differences in study hours based on parental education levels. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by parental education level
par(mfrow = c(1, 3))
hist(high_school_education_hrs, main = "High School Education", xlab = "Study Hours", col = "skyblue", border = "black")
hist(college_education_hrs, main = "College Education", xlab = "Study Hours", col = "skyblue", border = "black")
hist(postgraduate_education_hrs, main = "Postgraduate Education", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_school_education_hrs)

    Shapiro-Wilk normality test

data:  high_school_education_hrs
W = 0.99701, p-value = 0.07392
shapiro.test(college_education_hrs)

    Shapiro-Wilk normality test

data:  college_education_hrs
W = 0.99571, p-value = 0.1115
shapiro.test(postgraduate_education_hrs)

    Shapiro-Wilk normality test

data:  postgraduate_education_hrs
W = 0.99376, p-value = 0.1155

All three histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on parental education levels.

# ANOVA test for study hours by parental education level
anova_parental_education_level <- aov(Hours_Studied ~ Parental_Education_Level, data = student_data)
summary(anova_parental_education_level)
                           Df Sum Sq Mean Sq F value Pr(>F)
Parental_Education_Level    2     37   18.71   0.522  0.593
Residuals                6374 228374   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on parental education levels, with a p-value greater than 0.05. This indicates that parental education levels do not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of parental education levels.

# Chi-square test for study hours by parental education level
table_parental_education_hours <- table(student_data$Hours_Studied, student_data$Parental_Education_Level)
chisq.test(table_parental_education_hours)
Warning in chisq.test(table_parental_education_hours): Chi-squared
approximation may be incorrect

    Pearson's Chi-squared test

data:  table_parental_education_hours
X-squared = 73.306, df = 80, p-value = 0.6885

The Chi-square test shows that study hours are independent of parental education levels, with a p-value greater than 0.05. This further confirms that parental education levels do not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Distance from Home Category)

Next, we explore the average number of hours students study per week based on the distance from home to school.

# Sample the data
near_distance_hrs <- student_data$Hours_Studied[student_data$Distance_from_Home == "Near"][sample(sum(student_data$Distance_from_Home == "Near"), round(sum(student_data$Distance_from_Home == "Near")*sample_fraction))]
moderate_distance_hrs <- student_data$Hours_Studied[student_data$Distance_from_Home == "Moderate"][sample(sum(student_data$Distance_from_Home == "Moderate"), round(sum(student_data$Distance_from_Home == "Moderate")*sample_fraction))]
far_distance_hrs <- student_data$Hours_Studied[student_data$Distance_from_Home == "Far"][sample(sum(student_data$Distance_from_Home == "Far"), round(sum(student_data$Distance_from_Home == "Far")*sample_fraction))]

# Summary statistics for study hours by distance from home (Near, Moderate, Far
summary(near_distance_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1      16      20      20      24      39 
summary(moderate_distance_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   4.00   17.00   20.00   20.56   24.00   39.00 
summary(far_distance_hrs)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   5.00   16.00   21.00   20.29   24.00   36.00 

The summary statistics of the average number of hours students study per week based on the distance from home to school show no significant differences. We will now use ANOVA to test for differences in study hours based on the distance from home to school. But first, we need to check the assumptions of ANOVA.

# Histogram of study hours by distance from home
par(mfrow = c(1, 3))
hist(near_distance_hrs, main = "Near Distance from Home", xlab = "Study Hours", col = "skyblue", border = "black")
hist(moderate_distance_hrs, main = "Moderate Distance from Home", xlab = "Study Hours", col = "skyblue", border = "black")
hist(far_distance_hrs, main = "Far Distance from Home", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(near_distance_hrs)

    Shapiro-Wilk normality test

data:  near_distance_hrs
W = 0.99646, p-value = 0.01072
shapiro.test(moderate_distance_hrs)

    Shapiro-Wilk normality test

data:  moderate_distance_hrs
W = 0.99467, p-value = 0.04049
shapiro.test(far_distance_hrs)

    Shapiro-Wilk normality test

data:  far_distance_hrs
W = 0.99312, p-value = 0.513

The Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with far distance from home, but not for students with near and moderate distance from home. We will now use Kruksal-Wallis test to test for differences in study hours based on the distance from home to school.

# Kruskal-Wallis test for study hours by distance from home
kruskal.test(Hours_Studied ~ Distance_from_Home, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Distance_from_Home
Kruskal-Wallis chi-squared = 2.0964, df = 2, p-value = 0.3506

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on the distance from home to school, with a p-value greater than 0.05. This indicates that the distance from home to school does not have a significant impact on the number of hours students study per week.

Now we use Chi-square test to check whether study hours are independent of the distance from home to school.

# Chi-square test for study hours by distance from home
table_distance_from_home_hours <- table(student_data$Hours_Studied, student_data$Distance_from_Home)
chisq.test(table_distance_from_home_hours)
Warning in chisq.test(table_distance_from_home_hours): Chi-squared
approximation may be incorrect

    Pearson's Chi-squared test

data:  table_distance_from_home_hours
X-squared = 67.929, df = 80, p-value = 0.8299

The Chi-square test shows that study hours are independent of the distance from home to school, with a p-value greater than 0.05. This further confirms that the distance from home to school does not have a significant impact on the number of hours students study per week.

Summary of Average Number of Hours Students Study per Week

Based on our analysis, we found that the average number of hours students study per week is not significantly influenced by the following factors:

  1. Participation in extracurricular activities
  2. Motivation levels
  3. Access to resources
  4. Parental involvement
  5. Peer influence
  6. Learning disabilities
  7. Parental education levels
  8. Distance from home to school

Our analysis indicates that these factors do not have a significant impact on the number of hours students study per week. This suggests that students are able to allocate a consistent amount of time to studying regardless of these factors. This information can be valuable for educators and policymakers to understand student study habits and make informed decisions to support student learning. However, for internet access, we found that students with internet access tend to study more hours per week compared to students without internet access. This suggests that internet access may play a role in facilitating additional study time for students.

The variation in attendance rates across students

Now we analyze the variation in attendance rates across students.

# Sample the data
sample_attendance <- student_data$Attendance[sample(nrow(student_data), round(nrow(student_data)*sample_fraction))]

# Summary statistics for attendance rates
summary(sample_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    70.0    80.0    80.1    91.0   100.0 
# Histogram of attendance rates
hist(sample_attendance, main = "Distribution of Attendance Rates", xlab = "Attendance Rate", col = "skyblue", border = "black")

From the histogram we can see that the distribution of attendance rates is approximately uniform, ranging from approximately 60% to 100%. From this we can see that attendance rates are evenly distributed across students. The average attendance rate is approximately 79.75%, which is relatively high. We now investigate the factors that may influence attendance rates.

Attendance Rates by Parental Involvement

We will now explore the attendance rates based on parental involvement levels.

# Sample the data
high_parental_involvement_attendance <- student_data$Attendance[student_data$Parental_Involvement == "High"][sample(sum(student_data$Parental_Involvement == "High"), round(sum(student_data$Parental_Involvement == "High")*sample_fraction))]
medium_parental_involvement_attendance <- student_data$Attendance[student_data$Parental_Involvement == "Medium"][sample(sum(student_data$Parental_Involvement == "Medium"), round(sum(student_data$Parental_Involvement == "Medium")*sample_fraction))]
low_parental_involvement_attendance <- student_data$Attendance[student_data$Parental_Involvement == "Low"][sample(sum(student_data$Parental_Involvement == "Low"), round(sum(student_data$Parental_Involvement == "Low")*sample_fraction))]

# Summary statistics for attendance rates by parental involvement
summary(high_parental_involvement_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   69.00   79.00   79.32   89.00  100.00 
summary(medium_parental_involvement_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   80.21   91.00  100.00 
summary(low_parental_involvement_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   71.00   80.00   80.16   91.00  100.00 

The summary statistics of the attendance rates based on parental involvement levels show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on parental involvement levels.

# Histogram of attendance rates by parental involvement
par(mfrow = c(1, 3))
hist(high_parental_involvement_attendance, main = "High Parental Involvement", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(medium_parental_involvement_attendance, main = "Medium Parental Involvement", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(low_parental_involvement_attendance, main = "Low Parental Involvement", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruksal-Wallis test
kruskal.test(Attendance ~ Parental_Involvement, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Parental_Involvement
Kruskal-Wallis chi-squared = 1.2171, df = 2, p-value = 0.5441

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on parental involvement levels, with a p-value greater than 0.05. This indicates that parental involvement does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of parental involvement levels.

# Chi-square test for attendance rates by parental involvement
table_parental_involvement_attendance <- table(student_data$Attendance, student_data$Parental_Involvement)
chisq.test(table_parental_involvement_attendance)

    Pearson's Chi-squared test

data:  table_parental_involvement_attendance
X-squared = 88.103, df = 80, p-value = 0.2506

The Chi-square test shows that attendance rates are independent of parental involvement levels, with a p-value greater than 0.05. This further confirms that parental involvement does not have a significant impact on attendance rates.

Attendance Rates by Access to Resources

Next, we explore the attendance rates based on access to resources.

# Sample the data
high_access_to_resources_attendance <- student_data$Attendance[student_data$Access_to_Resources == "High"][sample(sum(student_data$Access_to_Resources == "High"), round(sum(student_data$Access_to_Resources == "High")*sample_fraction))]
medium_access_to_resources_attendance <- student_data$Attendance[student_data$Access_to_Resources == "Medium"][sample(sum(student_data$Access_to_Resources == "Medium"), round(sum(student_data$Access_to_Resources == "Medium")*sample_fraction))]
low_access_to_resources_attendance <- student_data$Attendance[student_data$Access_to_Resources == "Low"][sample(sum(student_data$Access_to_Resources == "Low"), round(sum(student_data$Access_to_Resources == "Low")*sample_fraction))]

# Summary statistics for attendance rates by access to resources
summary(high_access_to_resources_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   69.00   79.00   79.48   90.00  100.00 
summary(medium_access_to_resources_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   71.00   81.00   80.37   90.00  100.00 
summary(low_access_to_resources_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.25   81.00   80.45   91.00  100.00 

The summary statistics of the attendance rates based on access to resources show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on access to resources.

# Histogram of attendance rates by access to resources
par(mfrow = c(1, 3))
hist(high_access_to_resources_attendance, main = "High Access to Resources", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(medium_access_to_resources_attendance, main = "Medium Access to Resources", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(low_access_to_resources_attendance, main = "Low Access to Resources", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruksal-Wallis test
kruskal.test(Attendance ~ Access_to_Resources, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Access_to_Resources
Kruskal-Wallis chi-squared = 1.0494, df = 2, p-value = 0.5917

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on access to resources, with a p-value greater than 0.05. This indicates that access to resources does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of access to resources.

# Chi-square test for attendance rates by access to resources
table_access_to_resources_attendance <- table(student_data$Attendance, student_data$Access_to_Resources)
chisq.test(table_access_to_resources_attendance)

    Pearson's Chi-squared test

data:  table_access_to_resources_attendance
X-squared = 86.609, df = 80, p-value = 0.2874

The Chi-square test shows that attendance rates are independent of access to resources, with a p-value greater than 0.05. This further confirms that access to resources does not have a significant impact on attendance rates.

Attendance Rates by Extracurricular Activities

Next, we explore the attendance rates based on participation in extracurricular activities.

# Sample the data
participate_extracurricular_attendance <- student_data$Attendance[student_data$Extracurricular_Activities == "Yes"][sample(sum(student_data$Extracurricular_Activities == "Yes"), round(sum(student_data$Extracurricular_Activities == "Yes")*sample_fraction))]
do_not_participate_extracurricular_attendance <- student_data$Attendance[student_data$Extracurricular_Activities == "No"][sample(sum(student_data$Extracurricular_Activities == "No"), round(sum(student_data$Extracurricular_Activities == "No")*sample_fraction))]

# Summary statistics for attendance rates by extracurricular activities
summary(participate_extracurricular_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   79.00   79.58   89.00  100.00 
summary(do_not_participate_extracurricular_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    69.0    80.0    79.8    91.0   100.0 

The summary statistics of the attendance rates based on participation in extracurricular activities show no significant differences. We will now use Wilcoxon rank sum test to test for differences in attendance rates based on participation in extracurricular activities.

# Histogram of attendance rates by extracurricular activities
par(mfrow = c(1, 2))
hist(participate_extracurricular_attendance, main = "Extracurricular Activities", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(do_not_participate_extracurricular_attendance, main = "No Extracurricular Activities", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Wilcoxon rank sum test
wilcox.test(participate_extracurricular_attendance, do_not_participate_extracurricular_attendance)

    Wilcoxon rank sum test with continuity correction

data:  participate_extracurricular_attendance and do_not_participate_extracurricular_attendance
W = 435525, p-value = 0.6906
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank sum test shows that there is no significant difference in the average attendance rates based on participation in extracurricular activities, with a p-value greater than 0.05. This indicates that participation in extracurricular activities does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of participation in extracurricular activities.

# Chi-square test for attendance rates by extracurricular activities
table_extracurricular_activities_attendance <- table(student_data$Attendance, student_data$Extracurricular_Activities)
chisq.test(table_extracurricular_activities_attendance)

    Pearson's Chi-squared test

data:  table_extracurricular_activities_attendance
X-squared = 38.612, df = 40, p-value = 0.5327

The Chi-square test shows that attendance rates are independent of participation in extracurricular activities, with a p-value greater than 0.05. This further confirms that participation in extracurricular activities does not have a significant impact on attendance rates.

Attendance Rates by Motivational Level

Next, we explore attendance rates based on motivational levels.

# Sample the data
high_motivation_attendance <- student_data$Attendance[student_data$Motivation_Level == "High"][sample(sum(student_data$Motivation_Level == "High"), round(sum(student_data$Motivation_Level == "High")*sample_fraction))]
medium_motivation_attendance <- student_data$Attendance[student_data$Motivation_Level == "Medium"][sample(sum(student_data$Motivation_Level == "Medium"), round(sum(student_data$Motivation_Level == "Medium")*sample_fraction))]
low_motivation_attendance <- student_data$Attendance[student_data$Motivation_Level == "Low"][sample(sum(student_data$Motivation_Level == "Low"), round(sum(student_data$Motivation_Level == "Low")*sample_fraction))]

# Summary statistics for attendance rates by motivational levels
summary(high_motivation_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.50   80.00   80.01   90.50  100.00 
summary(medium_motivation_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   80.33   90.00  100.00 
summary(low_motivation_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   71.00   81.00   80.11   90.00  100.00 

The summary statistics of the attendance rates based on motivational levels show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on motivational levels.

# Histogram of attendance rates by motivational levels
par(mfrow = c(1, 3))
hist(high_motivation_attendance, main = "High Motivation Level", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(medium_motivation_attendance, main = "Medium Motivation Level", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(low_motivation_attendance, main = "Low Motivation Level", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruksal-Wallis test
kruskal.test(Attendance ~ Motivation_Level, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Motivation_Level
Kruskal-Wallis chi-squared = 0.86696, df = 2, p-value = 0.6482

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on motivational levels, with a p-value greater than 0.05. This indicates that motivation levels do not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of motivational levels.

# Chi-square test for attendance rates by motivational levels
table_motivation_level_attendance <- table(student_data$Attendance, student_data$Motivation_Level)
chisq.test(table_motivation_level_attendance)

    Pearson's Chi-squared test

data:  table_motivation_level_attendance
X-squared = 105.44, df = 80, p-value = 0.02994

The Chi-square test shows that attendance rates are independent of motivational levels, with a p-value greater than 0.05. This further confirms that motivation levels do not have a significant impact on attendance rates.

Attendance Rates by Internet Access

Next, we explore attendance rates based on internet access.

# Sample the data
internet_access_attendance <- student_data$Attendance[student_data$Internet_Access == "Yes"][sample(sum(student_data$Internet_Access == "Yes"), round(sum(student_data$Internet_Access == "Yes")*sample_fraction))]
no_internet_access_attendance <- student_data$Attendance[student_data$Internet_Access == "No"][sample(sum(student_data$Internet_Access == "No"), round(sum(student_data$Internet_Access == "No")*sample_fraction))]

# Summary statistics for attendance rates by internet access
summary(internet_access_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    70.0    80.0    80.1    90.0   100.0 
summary(no_internet_access_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  61.00   71.00   79.00   80.73   92.00  100.00 

The summary statistics of the attendance rates based on internet access show no significant differences. We will now use Wilcoxon rank sum test to test for differences in attendance rates based on internet access.

# Histogram of attendance rates by internet access
par(mfrow = c(1, 2))
hist(internet_access_attendance, main = "Internet Access", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(no_internet_access_attendance, main = "No Internet Access", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Wilcoxon rank sum test
wilcox.test(internet_access_attendance, no_internet_access_attendance)

    Wilcoxon rank sum test with continuity correction

data:  internet_access_attendance and no_internet_access_attendance
W = 124302, p-value = 0.5441
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank sum test shows that there is no significant difference in the average attendance rates based on internet access, with a p-value greater than 0.05. This indicates that internet access does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of internet access.

# Chi-square test for attendance rates by internet access
table_internet_access_attendance <- table(student_data$Attendance, student_data$Internet_Access)
chisq.test(table_internet_access_attendance)

    Pearson's Chi-squared test

data:  table_internet_access_attendance
X-squared = 36.35, df = 40, p-value = 0.6353

The Chi-square test shows that attendance rates are independent of internet access, with a p-value greater than 0.05. This further confirms that internet access does not have a significant impact on attendance rates.

Attendance Rates by Family Income Category

Next, we explore attendance rates based on family income levels.

# Sample the data
low_family_income_attendance <- student_data$Attendance[student_data$Family_Income == "Low"][sample(sum(student_data$Family_Income == "Low"), round(sum(student_data$Family_Income == "Low")*sample_fraction))]
medium_family_income_attendance <- student_data$Attendance[student_data$Family_Income == "Medium"][sample(sum(student_data$Family_Income == "Medium"), round(sum(student_data$Family_Income == "Medium")*sample_fraction))]
high_family_income_attendance <- student_data$Attendance[student_data$Family_Income == "High"][sample(sum(student_data$Family_Income == "High"), round(sum(student_data$Family_Income == "High")*sample_fraction))]

# Summary statistics for attendance rates by family income
summary(high_family_income_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   69.00   78.00   78.83   89.00  100.00 
summary(medium_family_income_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   79.00   79.82   90.00  100.00 
summary(low_family_income_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    70.0    80.0    80.2    91.0   100.0 

The summary statistics of the attendance rates based on family income levels show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on family income levels.

# Histogram of attendance rates by family income
par(mfrow = c(1, 3))
hist(low_family_income_attendance, main = "Low Family Income", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(medium_family_income_attendance, main = "Medium Family Income", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(high_family_income_attendance, main = "High Family Income", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruksal-Wallis test
kruskal.test(Attendance ~ Family_Income, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Family_Income
Kruskal-Wallis chi-squared = 1.3483, df = 2, p-value = 0.5096

The Kruksal-Wallis test shows that there is no significant difference in the average attendance rates based on family income levels, with a p-value greater than 0.05. This indicates that family income does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of family income levels.

# Chi-square test for attendance rates by family income
table_family_income_attendance <- table(student_data$Attendance, student_data$Family_Income)
chisq.test(table_family_income_attendance)

    Pearson's Chi-squared test

data:  table_family_income_attendance
X-squared = 87.54, df = 80, p-value = 0.2641

The Chi-square test shows that attendance rates are independent of family income levels, with a p-value greater than 0.05. This further confirms that family income does not have a significant impact on attendance rates.

Attendance Rates by Teacher Quality Category

Next, we explore attendance rates based on teacher quality levels.

# Sample the data
low_teacher_quality_attendance <- student_data$Attendance[student_data$Teacher_Quality == "Low"][sample(sum(student_data$Teacher_Quality == "Low"), round(sum(student_data$Teacher_Quality == "Low")*sample_fraction))]
medium_teacher_quality_attendance <- student_data$Attendance[student_data$Teacher_Quality == "Medium"][sample(sum(student_data$Teacher_Quality == "Medium"), round(sum(student_data$Teacher_Quality == "Medium")*sample_fraction))]
high_teacher_quality_attendance <- student_data$Attendance[student_data$Teacher_Quality == "High"][sample(sum(student_data$Teacher_Quality == "High"), round(sum(student_data$Teacher_Quality == "High")*sample_fraction))]

# Summary statistics for attendance rates by teacher quality
summary(low_teacher_quality_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   71.00   81.00   80.69   90.00   99.00 
summary(medium_teacher_quality_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   79.00   79.94   90.00  100.00 
summary(high_teacher_quality_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.50   80.00   80.01   90.00  100.00 

The summary statistics of the attendance rates based on teacher quality levels show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on teacher quality levels.

# Histogram of attendance rates by teacher quality
par(mfrow = c(1, 3))
hist(low_teacher_quality_attendance, main = "Low Teacher Quality", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(medium_teacher_quality_attendance, main = "Medium Teacher Quality", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(high_teacher_quality_attendance, main = "High Teacher Quality", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruksal-Wallis test
kruskal.test(Attendance ~ Teacher_Quality, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Teacher_Quality
Kruskal-Wallis chi-squared = 0.4118, df = 2, p-value = 0.8139

The Kruksal-Wallis test shows that there is no significant difference in the average attendance rates based on teacher quality levels, with a p-value greater than 0.05. This indicates that teacher quality does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of teacher quality levels.

# Chi-square test for attendance rates by teacher quality
table_teacher_quality_attendance <- table(student_data$Attendance, student_data$Teacher_Quality)
chisq.test(table_teacher_quality_attendance)

    Pearson's Chi-squared test

data:  table_teacher_quality_attendance
X-squared = 82.603, df = 80, p-value = 0.3989

The Chi-square test shows that attendance rates are independent of teacher quality levels, with a p-value greater than 0.05. This further confirms that teacher quality does not have a significant impact on attendance rates.

Attendance Rates by School Type Category

Next, we explore attendance rates based on school type.

# Sample the data
public_school_attendance <- student_data$Attendance[student_data$School_Type == "Public"][sample(sum(student_data$School_Type == "Public"), round(sum(student_data$School_Type == "Public")*sample_fraction))]
private_school_attendance <- student_data$Attendance[student_data$School_Type == "Private"][sample(sum(student_data$School_Type == "Private"), round(sum(student_data$School_Type == "Private")*sample_fraction))]

# Summary statistics for attendance rates by school type
summary(public_school_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   79.71   90.00  100.00 
summary(private_school_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    70.0    79.0    79.9    89.0   100.0 

The summary statistics of the attendance rates based on school type show no significant differences. We will now use Wilcoxon rank sum test to test for differences in attendance rates based on school type.

# Histogram of attendance rates by school type
par(mfrow = c(1, 2))
hist(public_school_attendance, main = "Public School", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(private_school_attendance, main = "Private School", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Wilcoxon rank sum test
wilcox.test(public_school_attendance, private_school_attendance)

    Wilcoxon rank sum test with continuity correction

data:  public_school_attendance and private_school_attendance
W = 384035, p-value = 0.742
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank sum test shows that there is no significant difference in the average attendance rates based on school type, with a p-value greater than 0.05. This indicates that school type does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of school type.

# Chi-square test for attendance rates by school type
table_school_type_attendance <- table(student_data$Attendance, student_data$School_Type)
chisq.test(table_school_type_attendance)

    Pearson's Chi-squared test

data:  table_school_type_attendance
X-squared = 31.828, df = 40, p-value = 0.8182

The Chi-square test shows that attendance rates are independent of school type, with a p-value greater than 0.05. This further confirms that school type does not have a significant impact on attendance rates.

Attendance Rates by Peer Influence Category

Next, we explore attendance rates based on peer influence levels.

# Sample the data
positive_peer_influence_attendance <- student_data$Attendance[student_data$Peer_Influence == "Positive"][sample(sum(student_data$Peer_Influence == "Positive"), round(sum(student_data$Peer_Influence == "Positive")*sample_fraction))]
negative_peer_influence_attendance <- student_data$Attendance[student_data$Peer_Influence == "Negative"][sample(sum(student_data$Peer_Influence == "Negative"), round(sum(student_data$Peer_Influence == "Negative")*sample_fraction))]
neutral_peer_influence_attendance <- student_data$Attendance[student_data$Peer_Influence == "Neutral"][sample(sum(student_data$Peer_Influence == "Neutral"), round(sum(student_data$Peer_Influence == "Neutral")*sample_fraction))]

# Summary statistics for attendance rates by peer influence
summary(positive_peer_influence_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   69.25   79.00   79.62   90.00  100.00 
summary(negative_peer_influence_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   79.45   88.50  100.00 
summary(neutral_peer_influence_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   80.28   91.00  100.00 

The summary statistics of the attendance rates based on peer influence levels show no significant differences. We will now use Kruksal-Wallis test to test for differences in attendance rates based on peer influence levels.

# Histogram of attendance rates by peer influence
par(mfrow = c(1, 3))
hist(positive_peer_influence_attendance, main = "Positive Peer Influence", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(negative_peer_influence_attendance, main = "Negative Peer Influence", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(neutral_peer_influence_attendance, main = "Neutral Peer Influence", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruksal-Wallis test
kruskal.test(Attendance ~ Peer_Influence, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Peer_Influence
Kruskal-Wallis chi-squared = 5.4005, df = 2, p-value = 0.06719

The Kruksal-Wallis test shows that there is no significant difference in the average attendance rates based on peer influence levels, with a p-value greater than 0.05. This indicates that peer influence does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of peer influence levels.

# Chi-square test for attendance rates by peer influence
table_peer_influence_attendance <- table(student_data$Attendance, student_data$Peer_Influence)
chisq.test(table_peer_influence_attendance)

    Pearson's Chi-squared test

data:  table_peer_influence_attendance
X-squared = 78.462, df = 80, p-value = 0.5277

The Chi-square test shows that attendance rates are independent of peer influence levels, with a p-value greater than 0.05. This further confirms that peer influence does not have a significant impact on attendance rates.

Attendance Rates by Learning Disability Category

Next, we explore attendance rates based on learning disability.

# Sample the data
learning_disabilities_attendance <- student_data$Attendance[student_data$Learning_Disabilities == "Yes"][sample(sum(student_data$Learning_Disabilities == "Yes"), round(sum(student_data$Learning_Disabilities == "Yes")*sample_fraction))]
no_learning_disabilities_attendance <- student_data$Attendance[student_data$Learning_Disabilities == "No"][sample(sum(student_data$Learning_Disabilities == "No"), round(sum(student_data$Learning_Disabilities == "No")*sample_fraction))]

# Summary statistics for attendance rates by learning disability
summary(learning_disabilities_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   69.00   78.00   78.97   90.00  100.00 
summary(no_learning_disabilities_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   71.00   80.00   80.41   90.00  100.00 

The summary statistics of the attendance rates based on learning disability show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on learning disability.

# Histogram of attendance rates by learning disability
par(mfrow = c(1, 2))
hist(learning_disabilities_attendance, main = "Learning Disabilities", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(no_learning_disabilities_attendance, main = "No Learning Disabilities", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Wilcoxon rank sum test
wilcox.test(learning_disabilities_attendance, no_learning_disabilities_attendance)

    Wilcoxon rank sum test with continuity correction

data:  learning_disabilities_attendance and no_learning_disabilities_attendance
W = 158910, p-value = 0.09363
alternative hypothesis: true location shift is not equal to 0

The Wilcoxon rank sum test shows that there is no significant difference in the average attendance rates based on learning disability, with a p-value greater than 0.05. This indicates that learning disabilities do not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of learning disabilities.

# Chi-square test for attendance rates by learning disabilities
table_learning_disabilities_attendance <- table(student_data$Attendance, student_data$Learning_Disabilities)
chisq.test(table_learning_disabilities_attendance)

    Pearson's Chi-squared test

data:  table_learning_disabilities_attendance
X-squared = 39.644, df = 40, p-value = 0.4862

The Chi-square test shows that attendance rates are independent of learning disabilities, with a p-value greater than 0.05. This further confirms that learning disabilities do not have a significant impact on attendance rates.

Attendance Rates by Parental Education Level Category

Next, we explore attendance rates based on parental education levels.

# Sample the data
high_school_education_attendance <- student_data$Attendance[student_data$Parental_Education_Level == "High School"][sample(sum(student_data$Parental_Education_Level == "High School"), round(sum(student_data$Parental_Education_Level == "High School")*sample_fraction))]
college_education_attendance <- student_data$Attendance[student_data$Parental_Education_Level == "College"][sample(sum(student_data$Parental_Education_Level == "College"), round(sum(student_data$Parental_Education_Level == "College")*sample_fraction))]
postgraduate_education_attendance <- student_data$Attendance[student_data$Parental_Education_Level == "Postgraduate"][sample(sum(student_data$Parental_Education_Level == "Postgraduate"), round(sum(student_data$Parental_Education_Level == "Postgraduate")*sample_fraction))]

# Summary statistics for attendance rates by parental education level
summary(high_school_education_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   69.00   80.00   79.83   90.00  100.00 
summary(college_education_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   72.00   81.00   80.86   91.00  100.00 
summary(postgraduate_education_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   72.00   82.00   81.21   91.00  100.00 

The summary statistics of the attendance rates based on parental education levels show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on parental education levels.

# Histogram of attendance rates by parental education level
par(mfrow = c(1, 3))
hist(high_school_education_attendance, main = "High School Education", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(college_education_attendance, main = "College Education", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(postgraduate_education_attendance, main = "Postgraduate Education", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruskal-Wallis test
kruskal.test(Attendance ~ Parental_Education_Level, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Parental_Education_Level
Kruskal-Wallis chi-squared = 4.5494, df = 2, p-value = 0.1028

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on parental education levels, with a p-value greater than 0.05. This indicates that parental education levels do not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of parental education levels.

# Chi-square test for attendance rates by parental education levels
table_parental_education_attendance <- table(student_data$Attendance, student_data$Parental_Education_Level)
chisq.test(table_parental_education_attendance)

    Pearson's Chi-squared test

data:  table_parental_education_attendance
X-squared = 95.274, df = 80, p-value = 0.117

The Chi-square test shows that attendance rates are independent of parental education levels, with a p-value greater than 0.05. This further confirms that parental education levels do not have a significant impact on attendance rates.

Attendance Rates by Distance from Home Category

Next, we explore attendance rates based on distance from home to school.

# Sample the data
near_distance_attendance <- student_data$Attendance[student_data$Distance_from_Home == "Near"][sample(sum(student_data$Distance_from_Home == "Near"), round(sum(student_data$Distance_from_Home == "Near")*sample_fraction))]
moderate_distance_attendance <- student_data$Attendance[student_data$Distance_from_Home == "Moderate"][sample(sum(student_data$Distance_from_Home == "Moderate"), round(sum(student_data$Distance_from_Home == "Moderate")*sample_fraction))]
far_distance_attendance <- student_data$Attendance[student_data$Distance_from_Home == "Far"][sample(sum(student_data$Distance_from_Home == "Far"), round(sum(student_data$Distance_from_Home == "Far")*sample_fraction))]

# Summary statistics for attendance rates by distance from home
summary(near_distance_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   79.99   90.00  100.00 
summary(moderate_distance_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    70.0    79.0    79.7    89.0   100.0 
summary(far_distance_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   69.00   78.00   79.26   89.00  100.00 

The summary statistics of the attendance rates based on distance from home to school show no significant differences. We will now use Kruskal-Wallis test to test for differences in attendance rates based on distance from home.

# Histogram of attendance rates by distance from home
par(mfrow = c(1, 3))
hist(near_distance_attendance, main = "Near Distance from Home", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(moderate_distance_attendance, main = "Moderate Distance from Home", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(far_distance_attendance, main = "Far Distance from Home", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Kruskal-Wallis test
kruskal.test(Attendance ~ Distance_from_Home, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Distance_from_Home
Kruskal-Wallis chi-squared = 2.6986, df = 2, p-value = 0.2594

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on the distance from home to school, with a p-value greater than 0.05. This indicates that the distance from home to school does not have a significant impact on attendance rates.

Now we use Chi-square test to check whether attendance rates are independent of distance from home to school.

# Chi-square test for attendance rates by distance from home
table_distance_from_home_attendance <- table(student_data$Attendance, student_data$Distance_from_Home)
chisq.test(table_distance_from_home_attendance)

    Pearson's Chi-squared test

data:  table_distance_from_home_attendance
X-squared = 80.024, df = 80, p-value = 0.4782

The Chi-square test shows that attendance rates are independent of distance from home to school, with a p-value greater than 0.05. This further confirms that the distance from home to school does not have a significant impact on attendance rates.

Summary of Attendance Rates

Based on our analysis, we found that the following factors do not have a significant impact on attendance rates:

  • Parental Involvement
  • Access to Resources
  • Extracurricular Activities
  • Motivational Level
  • Internet Access
  • Family Income
  • Teacher Quality
  • School Type
  • Peer Influence
  • Learning Disabilities
  • Parental Education Level
  • Distance from Home to School

These findings suggest that other factors not included in the dataset may have a more significant impact on student attendance rates.

The distribution of parental involvement levels among students

Now we analyze the distribution of parental involvement levels among students.

# Count of parental involvement levels
table(student_data$Parental_Involvement)

  High    Low Medium 
  1836   1290   3251 
# Bar plot of parental involvement levels
barplot(table(student_data$Parental_Involvement), main = "Distribution of Parental Involvement Levels", xlab = "Parental Involvement Levels", ylab = "Frequency", col = "skyblue", border = "black")

The distribution of parental involvement levels among students is as follows:

  • High: 1836 students
  • Low: 1290 students
  • Medium: 3251 students

We can see that the majority of students have medium parental involvement levels, followed by high parental involvement levels, and low parental involvement levels.

The distribution of parental involvement levels among students by Family Income Category

We now explore the distribution of parental involvement levels among students based on family income levels.

# Count of parental involvement levels by family income
table(student_data$Parental_Involvement, student_data$Family_Income)
        
         High  Low Medium
  High    353  746    737
  Low     240  553    497
  Medium  636 1283   1332
# Bar plot of parental involvement levels by family income
par(mfrow = c(1, 3))
barplot(table(student_data$Parental_Involvement[student_data$Family_Income == "Low"]), main = "Low Family Income", xlab = "Parental Involvement Levels", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Parental_Involvement[student_data$Family_Income == "Medium"]), main = "Medium Family Income", xlab = "Parental Involvement Levels", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Parental_Involvement[student_data$Family_Income == "High"]), main = "High Family Income", xlab = "Parental Involvement Levels", ylab = "Frequency", col = "skyblue", border = "black")

  • The Low Family Income group has the highest counts across all levels of parental involvement, suggesting that more students in the dataset come from low-income families.
  • Students with Medium Parental Involvement and Medium Family Income form the largest single group (1332 students).
  • Students with Low Parental Involvement and High Family Income form the smallest single group (240 students).

The distribution of parental involvement levels among students by Parental Education Level Category

We now explore the distribution of parental involvement levels among students based on parental education levels.

# Count of parental involvement levels by parental education level
table(student_data$Parental_Involvement, student_data$Parental_Education_Level)
        
         College High School Postgraduate
  High       576         902          358
  Low        403         622          265
  Medium     960        1634          657
# Bar plot of parental involvement levels by parental education level
par(mfrow = c(1, 3))
barplot(table(student_data$Parental_Involvement[student_data$Parental_Education_Level == "High School"]), main = "High School Education", xlab = "Parental Involvement Levels", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Parental_Involvement[student_data$Parental_Education_Level == "College"]), main = "College Education", xlab = "Parental Involvement Levels", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Parental_Involvement[student_data$Parental_Education_Level == "Postgraduate"]), main = "Postgraduate Education", xlab = "Parental Involvement Levels", ylab = "Frequency", col = "skyblue", border = "black")

  • High School Education: The largest counts across all levels of Parental Involvement are observed in families where the parental education level is “High School.” For example, the highest count is for Medium Parental Involvement with parents educated at the high school level (1634 students).
  • Postgraduate Education: The smallest counts are generally in families where the parental education level is “Postgraduate,” suggesting that fewer students’ parents fall into this category. For example, only 265 students with Low Parental Involvement have parents with postgraduate education.
  • College Education: Counts are intermediate, with Medium Parental Involvement having the highest representation (960 students).

The proportion of students with access to educational resources

We now analyze the proportion of students with access to educational resources.

# Count of access to resources
table(student_data$Access_to_Resources)

  High    Low Medium 
  1900   1274   3203 
# Bar plot of access to resources
barplot(table(student_data$Access_to_Resources), main = "Distribution of Access to Resources", xlab = "Access to Resources", ylab = "Frequency", col = "skyblue", border = "black")

High Low Medium 1900 1274 3203

The distribution of access to resources among students is as follows:

  • High: 1900 students
  • Low: 1274 students
  • Medium: 3203 students

We can see that the majority of students have medium access to educational resources, followed by high access to resources, and low access to resources.

The proportion of students with access to educational resources by Family Income Category

We now explore the proportion of students with access to educational resources based on family income levels.

# Count of access to resources by family income
table(student_data$Access_to_Resources, student_data$Family_Income)
        
         High  Low Medium
  High    369  798    733
  Low     237  517    520
  Medium  623 1267   1313
# Bar plot of access to resources by family income
par(mfrow = c(1, 3))
barplot(table(student_data$Access_to_Resources[student_data$Family_Income == "Low"]), main = "Low Family Income", xlab = "Access to Resources", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Access_to_Resources[student_data$Family_Income == "Medium"]), main = "Medium Family Income", xlab = "Access to Resources", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Access_to_Resources[student_data$Family_Income == "High"]), main = "High Family Income", xlab = "Access to Resources", ylab = "Frequency", col = "skyblue", border = "black")

  • Low Income Families: Students from Low Income families tend to have the largest counts in Medium Access to Resources (1267 students), suggesting moderate access to resources even for lower-income groups.
  • High Income Families: Students from High Income families are more likely to have High Access to Resources (369 students) than Low Access to Resources (237 students).
  • Medium Income Families: Students from Medium Income families dominate the Medium Access to Resources category (1313 students), indicating a balanced availability of resources.

The proportion of students with access to educational resources by Parental Education Level Category

We now explore the proportion of students with access to educational resources based on parental education levels.

# Count of access to resources by parental education level
table(student_data$Access_to_Resources, student_data$Parental_Education_Level)
        
         College High School Postgraduate
  High       564         963          373
  Low        371         645          258
  Medium    1004        1550          649
# Bar plot of access to resources by parental education level
par(mfrow = c(1, 3))
barplot(table(student_data$Access_to_Resources[student_data$Parental_Education_Level == "High School"]), main = "High School Education", xlab = "Access to Resources", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Access_to_Resources[student_data$Parental_Education_Level == "College"]), main = "College Education", xlab = "Access to Resources", ylab = "Frequency", col = "skyblue", border = "black")
barplot(table(student_data$Access_to_Resources[student_data$Parental_Education_Level == "Postgraduate"]), main = "Postgraduate Education", xlab = "Access to Resources", ylab = "Frequency", col = "skyblue", border = "black")

  • High School Education: Parents with High School education have the highest counts in all access levels, particularly Medium Access to Resources (1550 students). This suggests that a significant number of students with parents in this category experience moderate access to resources.
  • College Education: Students whose parents have College education mostly fall into the Medium Access to Resources category (1004 students). A considerable proportion also have High Access to Resources (564 students).
  • Postgraduate Education: Students with parents who have a Postgraduate education show a higher likelihood of High Access to Resources (373 students) compared to Low Access to Resources (258 students).

The variation in sleep hours across different levels of extracurricular participation

We now analyze the variation in sleep hours across different levels of extracurricular participation. But first we explore the distribution of sleeping hours.

sleep_hrs_data <- student_data$Sleep_Hours

# Summary statistics for sleeping hours
summary(sleep_hrs_data)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  4.000   6.000   7.000   7.035   8.000  10.000 
# Histogram of sleeping hours
hist(sleep_hrs_data, main = "Distribution of Sleeping Hours", xlab = "Sleeping Hours", col = "skyblue", border = "black")

# Shapiro-Wilk test for normality
shapiro.test(sleep_hrs_data[sample(length(sleep_hrs_data), round(length(sleep_hrs_data)*sample_fraction))])

    Shapiro-Wilk normality test

data:  sleep_hrs_data[sample(length(sleep_hrs_data), round(length(sleep_hrs_data) * sample_fraction))]
W = 0.95293, p-value < 2.2e-16

From the histogram the distribution appears to be normally distributed with hours ranging from 4 to 10. However, the Shapiro-Wilk test for normality shows that the data is not normally distributed.

Variation in sleep hours across different levels of extracurricular participation

We now analyze the variation in sleep hours across different levels of extracurricular participation.

# Sample the data
participate_extracurricular_sleep <- student_data$Sleep_Hours[student_data$Extracurricular_Activities == "Yes"][sample(sum(student_data$Extracurricular_Activities == "Yes"), round(sum(student_data$Extracurricular_Activities == "Yes")*sample_fraction))]
do_not_participate_extracurricular_sleep <- student_data$Sleep_Hours[student_data$Extracurricular_Activities == "No"][sample(sum(student_data$Extracurricular_Activities == "No"), round(sum(student_data$Extracurricular_Activities == "No")*sample_fraction))]

# Summary statistics for sleep hours by extracurricular activities
summary(participate_extracurricular_sleep)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  4.000   6.000   7.000   7.113   8.000  10.000 
summary(do_not_participate_extracurricular_sleep)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  4.000   6.000   7.000   7.026   8.000  10.000 
# Histogram of sleep hours by extracurricular activities
par(mfrow = c(1, 2))
hist(participate_extracurricular_sleep, main = "Extracurricular Activities", xlab = "Sleep Hours", col = "skyblue", border = "black")
hist(do_not_participate_extracurricular_sleep, main = "No Extracurricular Activities", xlab = "Sleep Hours", col = "skyblue", border = "black")

# Wilcoxon rank sum test
wilcox.test(participate_extracurricular_sleep, do_not_participate_extracurricular_sleep)

    Wilcoxon rank sum test with continuity correction

data:  participate_extracurricular_sleep and do_not_participate_extracurricular_sleep
W = 450744, p-value = 0.3653
alternative hypothesis: true location shift is not equal to 0
LS0tDQp0aXRsZTogIkdlbmVyYWwgVHJlbmRzIGFuZCBEZXNjcmlwdGl2ZSBBbmFseXNpcyINCmF1dGhvcjogIiZjb3B5OyBIZWN0b3IgTWF0aG9uc2kiDQpkYXRlOiAyMDI0LTEwLTE5DQpvdXRwdXQ6DQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgdGhlbWU6IGZsYXRseQ0KICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICB0b2NfZmxvYXQ6IHRydWUNCi0tLQ0KDQotLS0tLQ0KDQojIEFic3RyYWN0DQoNClRoaXMgcmVwb3J0IGV4cGxvcmVzIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaW91cyBmYWN0b3JzIGluZmx1ZW5jaW5nIHN0dWRlbnQgcGVyZm9ybWFuY2UsIHVzaW5nIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgKEVEQSkgdG8gaWRlbnRpZnkga2V5IHRyZW5kcyBhbmQgY29ycmVsYXRpb25zLiBUaGUgYW5hbHlzaXMgZm9jdXNlcyBvbiB2YXJpYWJsZXMgc3VjaCBhcyBzdHVkeSBoYWJpdHMsIGFjY2VzcyB0byByZXNvdXJjZXMsIHBhcmVudGFsIGludm9sdmVtZW50LCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzLCBhbmQgaG93IHRoZXkgaW1wYWN0IGZpbmFsIGV4YW0gc2NvcmVzLiBJbnNpZ2h0cyBnYWluZWQgZnJvbSB0aGUgZGF0YSB3aWxsIGluZm9ybSByZWNvbW1lbmRhdGlvbnMgYWltZWQgYXQgaW1wcm92aW5nIGFjYWRlbWljIG91dGNvbWVzIGZvciBzdHVkZW50cy4NCg0KIyBEYXRhIFNvdXJjZQ0KDQpUaGUgZGF0YXNldCB3YXMgc291cmNlZCBmcm9tIEthZ2dsZSB1bmRlciB0aGUgQ0MwIDEuMCB1bml2ZXJzYWwgIk5vIENvcHlyaWdodCIgbGljZW5zZS4gV2UgYXJlIGZyZWUgdG8gY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIGFuZCBwZXJmb3JtIHRoZSB3b3JrLCBldmVuIGZvciBjb21tZXJjaWFsIHB1cnBvc2VzLCBhbGwgd2l0aG91dCBhc2tpbmcgcGVybWlzc2lvbi4gTGVhcm4gbW9yZSBhYm91dCB0aGlzIGxpY2Vuc2UgaGVyZSBbaGVyZV0oaHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL3B1YmxpY2RvbWFpbi96ZXJvLzEuMC8pLg0KDQpVUkwgZm9yIGRhdGEgaW4gS2FnZ2xlOiBbU3R1ZGVudCBQZXJmb3JtYW5jZSBGYWN0b3JzIERhdGFzZXRdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvbGFpbmd1eW4xMjMvc3R1ZGVudC1wZXJmb3JtYW5jZS1mYWN0b3JzKQ0KDQojIEltcG9ydCBhbmQgVmlldyBEYXRhDQoNCmBgYHtyfQ0Kc3R1ZGVudF9kYXRhIDwtIHJlYWQuY3N2KCcuLi9kYXRhL1N0dWRlbnRQZXJmb3JtYW5jZUZhY3RvcnMuY3N2JywgaGVhZGVyID0gVFJVRSkNCnN0dWRlbnRfZGF0YSAgICAjIERpc3BsYXkgdGhlIGRhdGFzZXQNCnNhbXBsZV9mcmFjdGlvbiA8LSAwLjMNCmBgYA0KDQojIyMgU3VtbWFyeSBTdGF0aXN0aWNzDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGFsbCB2YXJpYWJsZXMNCnN1bW1hcnkoc3R1ZGVudF9kYXRhKSAgICMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhbGwgdmFyaWFibGVzDQpoZWFkKHN0dWRlbnRfZGF0YSkgICAgICAjIERpc3BsYXkgdGhlIGZpcnN0IGZldyByb3dzIG9mIHRoZSBkYXRhc2V0DQpzdHIoc3R1ZGVudF9kYXRhKSAgICAgICAjIFN0cnVjdHVyZSBvZiB0aGUgZGF0YXNldA0Kc3VtKGlzLm5hKHN0dWRlbnRfZGF0YSkpICAgICMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzDQpgYGANCg0KIyBEYXRhIENsZWFuaW5nDQoNCiMjIyBNaXNzaW5nIFZhbHVlcw0KV2Ugbm93IGNoZWNrIHdoZXRoZXIgdGhlIGRhdGFzZXQgY29udGFpbnMgYW55IG1pc3NpbmcgdmFsdWVzIGFuZCByZW1vdmUgdGhlbSBpZiBuZWNlc3NhcnkuDQoNCmBgYHtyfQ0KIyBDaGVjayBtaXNzaW5nIHZhbHVlcyBpbiBlYWNoIGNvbHVtbg0KY29sU3Vtcyhpcy5uYShzdHVkZW50X2RhdGEpKQ0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgbm8gbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGRhdGFzZXQuDQoNCldlIG5vdyBjaGVjayB0aGUgdW5pcXVlIHZhbHVlcyBpbiBlYWNoIGNhdGVnb3JpY2FsIGNvbHVtbiB0byBpZGVudGlmeSBhbnkgaW5jb25zaXN0ZW5jaWVzLg0KDQpgYGB7cn0NCiMgVW5pcXVlIHZhbHVlcyBpbiBlYWNoIGNhdGVnb3JpY2FsIGNvbHVtbg0KbGFwcGx5KHN0dWRlbnRfZGF0YVssIHNhcHBseShzdHVkZW50X2RhdGEsIGlzLmNoYXJhY3RlcildLCB1bmlxdWUpDQpgYGANCg0KRnJvbSB0aGUgcmVzdWx0cyBhYm92ZSB3ZSBjYW4gVGVhY2hlcl9RdWFsaXR5LCBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgYW5kIERpc3RhbmNlX2Zyb21fSG9tZSBoYXZlIG1pc3NpbmcgdmFsdWVzLiBXZSB3aWxsIG5vdyBpbnZlc3RpZ2F0ZSBmdXJ0aGVyIHRvIHNlZSBleGFjdGx5IHdoYXQgdGhlc2UgbWlzc2luZyB2YWx1ZXMgYXJlLg0KDQpgYGB7cn0NCiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzIGluIFRlYWNoZXJfUXVhbGl0eQ0KdGVhY2hlcl9xdWFsaXR5X21pc3NpbmcgPC0gc3R1ZGVudF9kYXRhW3N0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIiIsXQ0KdGVhY2hlcl9xdWFsaXR5X21pc3NpbmcNCm5yb3codGVhY2hlcl9xdWFsaXR5X21pc3NpbmcpDQpgYGANCg0KV2UgY2FuIHNlZSB0aGF0IG9ubHkgNzggcm93cyBoYXZlIG1pc3NpbmcgdmFsdWVzIGluIHRoZSBUZWFjaGVyX1F1YWxpdHkgY29sdW1uLiBXZSB3aWxsIG5vdyBpbnZlc3RpZ2F0ZSB0aGUgUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsIGNvbHVtbi4NCg0KYGBge3J9DQojIENoZWNrIGZvciBtaXNzaW5nIHZhbHVlcyBpbiBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwNCnBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbF9taXNzaW5nIDwtIHN0dWRlbnRfZGF0YVtzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICIiLF0NCnBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbF9taXNzaW5nDQpucm93KHBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbF9taXNzaW5nKQ0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCA5MCByb3dzIGhhdmUgbWlzc2luZyB2YWx1ZXMgaW4gdGhlIFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCBjb2x1bW4uIFdlIHdpbGwgbm93IGludmVzdGlnYXRlIHRoZSBEaXN0YW5jZV9mcm9tX0hvbWUgY29sdW1uLg0KDQpgYGB7cn0NCiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzIGluIERpc3RhbmNlX2Zyb21fSG9tZQ0KZGlzdGFuY2VfZnJvbV9ob21lX21pc3NpbmcgPC0gc3R1ZGVudF9kYXRhW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIiIsXQ0KZGlzdGFuY2VfZnJvbV9ob21lX21pc3NpbmcNCm5yb3coZGlzdGFuY2VfZnJvbV9ob21lX21pc3NpbmcpDQpgYGANCg0KV2UgY2FuIHNlZSB0aGF0IDY3IHJvd3MgaGF2ZSBtaXNzaW5nIHZhbHVlcyBpbiB0aGUgRGlzdGFuY2VfZnJvbV9Ib21lIGNvbHVtbi4gQWxsIHRoZSBtaXNzaW5nIHZhbHVlcyBjb21iaW5lZCBtYWtlIHVwIGxlc3MgdGhhbiAxMCUgb2YgdGhlIGRhdGFzZXQuIFdlIHdpbGwgcmVtb3ZlIHRoZXNlIHJvd3MgZnJvbSB0aGUgZGF0YXNldC4NCg0KYGBge3J9DQojIFJlbW92ZSByb3dzIHdpdGggbWlzc2luZyB2YWx1ZXMNCnN0dWRlbnRfZGF0YSA8LSBzdWJzZXQoc3R1ZGVudF9kYXRhLCBUZWFjaGVyX1F1YWxpdHkgIT0gIiIgJiBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgIT0gIiIgJiBEaXN0YW5jZV9mcm9tX0hvbWUgIT0gIiIpDQoNCiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzDQpsYXBwbHkoc3R1ZGVudF9kYXRhWywgc2FwcGx5KHN0dWRlbnRfZGF0YSwgaXMuY2hhcmFjdGVyKV0sIHVuaXF1ZSkNCmBgYA0KDQojIyMgT3V0bGllcnMNCg0KV2Ugbm93IGludmVzdGlnYXRlIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUsIEZpbmFsX0V4YW1fU2NvcmUsIHRvIGlkZW50aWZ5IGFueSBvdXRsaWVycy4NCg0KYGBge3J9DQojIE91dGxpZXJzIGluIEZpbmFsX0V4YW1fU2NvcmUNCm91dGxpZXJzX2luX2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhW3N0dWRlbnRfZGF0YSRFeGFtX1Njb3JlID4gMTAwLF0NCm91dGxpZXJzX2luX2V4YW1fc2NvcmUNCg0KIyBSZW1vdmluZyBvdXRsaWVycw0Kc3R1ZGVudF9kYXRhIDwtIHN1YnNldChzdHVkZW50X2RhdGEsIEV4YW1fU2NvcmUgPD0gMTAwKQ0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCBvbmx5IDEgc3R1ZGVudCBnb3QgZXhhbSBzY29yZSBvZiAxMDEgd2hpY2ggaXMgYW4gb3V0bGllci4gV2Ugd2lsbCByZW1vdmUgdGhpcyByb3cgZnJvbSB0aGUgZGF0YXNldC4NCg0KYGBge3J9DQojIFJlbW92ZSBvdXRsaWVycw0Kc3R1ZGVudF9kYXRhIDwtIHN1YnNldChzdHVkZW50X2RhdGEsIEV4YW1fU2NvcmUgPD0gMTAwKQ0KYGBgDQoNCg0KIyBEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMNCg0KIyMjIERpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyAoV2l0aG91dCBDb25zaWRlcmluZyBPdGhlciBGYWN0b3JzKQ0KSGVyZSB3ZSB3aWxsIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBhbW9uZyBzdHVkZW50cyB3aXRoIHdpdGhvdXQgY29uc2lkZXJpbmcgb3RoZXIgZmFjdG9ycy4NClRvIGZpbmQgb3VyIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMsIHdlIGZpcnN0IG5lZWQgdG8gc2FtcGxlIHRoZSBkYXRhIGFuZCBwbG90IGEgaGlzdG9ncmFtLg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0Kc2V0LnNlZWQoMTIzKQ0KZXhhbV9zY29yZV9zYW1wbGUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc2FtcGxlKG5yb3coc3R1ZGVudF9kYXRhKSwgcm91bmQobnJvdyhzdHVkZW50X2RhdGEpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFBsb3QgaGlzdG9ncmFtDQpoaXN0KGV4YW1fc2NvcmVfc2FtcGxlLCBtYWluID0gIkRpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQpGcm9tIHRoZSBoaXN0b2dyYW0sIHdlIGNhbiBzZWUgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGlzIHBvc2l0aXZlbHkgc2tld2VkLCB3aXRoIG1vc3Qgc3R1ZGVudHMgc2NvcmluZyBiZXR3ZWVuIDYwIGFuZCA3NS4gVGhlcmUgYXJlIGEgZmV3IHN0dWRlbnRzIHdobyBzY29yZWQgYmVsb3cgNjAgYW5kIGEgZmV3IG91dGxpZXJzIHdobyBzY29yZWQgYWJvdmUgODAuIFdlIHdpbGwgbm93IGNyZWF0ZSBhIGJveHBsb3QgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gZnVydGhlci4NCmBgYHtyfQ0KIyBCb3hwbG90IG9mIGZpbmFsIGV4YW0gc2NvcmVzDQpib3hwbG90KGV4YW1fc2NvcmVfc2FtcGxlLCBtYWluID0gIkJveHBsb3Qgb2YgRmluYWwgRXhhbSBTY29yZXMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KVGhlIGJveHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3Jlcywgd2l0aCB0aGUgbWVkaWFuIHNjb3JlIGFyb3VuZCA3MC4gVGhlcmUgYXJlIGEgZmV3IG91dGxpZXJzIGFib3ZlIDgwLCBpbmRpY2F0aW5nIHRoYXQgc29tZSBzdHVkZW50cyBwZXJmb3JtZWQgZXhjZXB0aW9uYWxseSB3ZWxsLiBXZSB3aWxsIG5vdyB1c2UgbnVtZXJpY2FsIG1ldGhvZHMgdG8gY29uZmlybSB0aGUgbm9ybWFsaXR5IG9mIHRoZSBkaXN0cmlidXRpb24uDQpgYGB7cn0NCiMgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eQ0Kc2hhcGlyby50ZXN0KGV4YW1fc2NvcmVfc2FtcGxlKQ0KYGBgDQoNClRoZSBTaGFwaXJvLVdpbGsgdGVzdCBjb25maXJtcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgbm90IG5vcm1hbCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuDQoNCiMjIyBEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMgKFBhcmVudGFsX0ludm9sdmVtZW50IENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLiBXZSB3aWxsIGNyZWF0ZSBhIGJveHBsb3QgdG8gY29tcGFyZSB0aGUgc2NvcmVzIG9mIHN0dWRlbnRzIHdpdGggZGlmZmVyZW50IGxldmVscyBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudC4NCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmhpZ2hfcGFyZW50YWxfaW52b2x2ZW1lbnRfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiSGlnaCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJIaWdoIikqc2FtcGxlX2ZyYWN0aW9uKSldDQptZWRpdW1fcGFyZW50YWxfaW52b2x2ZW1lbnRfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJNZWRpdW0iKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTWVkaXVtIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnRfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTG93Iikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IHBhcmVudGFsIGludm9sdmVtZW50DQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX3BhcmVudGFsX2ludm9sdmVtZW50X2V4YW1fc2NvcmUsIG1haW4gPSAiSGlnaCBQYXJlbnRhbCBJbnZvbHZlbWVudCIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50X2V4YW1fc2NvcmUsIG1haW4gPSAiTWVkaXVtIFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnRfZXhhbV9zY29yZSwgbWFpbiA9ICJMb3cgUGFyZW50YWwgSW52b2x2ZW1lbnQiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KLSAqKkhpZ2ggUGFyZW50YWwgSW52b2x2ZW1lbnQqKjogVGhlIGRpc3RyaWJ1dGlvbiBpcyBwb3NpdGl2ZWx5IHNrZXdlZCwgd2l0aCBtb3N0IHNjb3JlcyBiZXR3ZWVuICoqYDYwYCoqIGFuZCAqKmA4MGAqKi4gVGhlcmUgYXJlIGEgZmV3IG91dGxpZXJzIGFib3ZlIDgwLCBpbmRpY2F0aW5nIGV4Y2VwdGlvbmFsIHBlcmZvcm1hbmNlLg0KLSAqKk1lZGl1bSBQYXJlbnRhbCBJbnZvbHZlbWVudCoqOiBUaGUgZGlzdHJpYnV0aW9uIGlzIHNpbWlsYXIgdG8gaGlnaCBwYXJlbnRhbCBpbnZvbHZlbWVudCwgd2l0aCBtb3N0IHNjb3JlcyBiZXR3ZWVuICoqYDYwYCoqIGFuZCAqKmA4MGAqKi4gVGhlcmUgYXJlIGEgZmV3IG91dGxpZXJzIGFib3ZlIDgwLCBpbmRpY2F0aW5nIGV4Y2VwdGlvbmFsIHBlcmZvcm1hbmNlLg0KLSAqKkxvdyBQYXJlbnRhbCBJbnZvbHZlbWVudCoqOiBUaGUgZGlzdHJpYnV0aW9uIGFwcGVhcnMgdG8gYmUgbW9yZSBzcHJlYWQgb3V0IGNvbXBhcmVkIHRvIGhpZ2ggYW5kIG1lZGl1bSBwYXJlbnRhbCBpbnZvbHZlbWVudCwgd2l0aCBzY29yZXMgcmFuZ2luZyBmcm9tICoqYDU1YCoqIHRvICoqYDc1YCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuDQoNCmBgYHtyfQ0KIyBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzaGFwaXJvLnRlc3QoaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudF9leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KG1lZGl1bV9wYXJlbnRhbF9pbnZvbHZlbWVudF9leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KGxvd19wYXJlbnRhbF9pbnZvbHZlbWVudF9leGFtX3Njb3JlKQ0KYGBgDQoNClRoZSBTaGFwaXJvLVdpbGsgdGVzdCBjb25maXJtcyB0aGF0IHRoZSBkaXN0cmlidXRpb25zIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGZvciBhbGwgc3R1ZGVudHMgd2l0aCBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBhcmUgbm90IG5vcm1hbCwgd2l0aCBwLXZhbHVlcyBsZXNzIHRoYW4gMC4wNS4NCg0KTm93IHdlIHRha2UgaXQgYSBzdGVwIGZ1cnRoZXIgYnkgY2hlY2tpbmcgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGlzIGRpZmZlcmVudCBiYXNlZCBvbiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMgdXNpbmcgS3J1c2thbC1XYWxsaXMgdGVzdC4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgcGFyZW50YWwgaW52b2x2ZW1lbnQNCnN1bW1hcnkoaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudF9leGFtX3Njb3JlKQ0Kc3VtbWFyeShtZWRpdW1fcGFyZW50YWxfaW52b2x2ZW1lbnRfZXhhbV9zY29yZSkNCnN1bW1hcnkobG93X3BhcmVudGFsX2ludm9sdmVtZW50X2V4YW1fc2NvcmUpDQoNCiMgS3J1c2thbC1XYWxsaXMgdGVzdCBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgcGFyZW50YWwgaW52b2x2ZW1lbnQNCmtydXNrYWwudGVzdChFeGFtX1Njb3JlIH4gUGFyZW50YWxfSW52b2x2ZW1lbnQsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydXNrYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGxlc3MgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHBhcmVudGFsIGludm9sdmVtZW50IGhhcyBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgZmluYWwgZXhhbSBzY29yZXMuIEZyb20gdGhlIHN1bW1hcnkgc3RhdGlzdGljcywgd2UgY2FuIHNlZSB0aGF0IHN0dWRlbnRzIHdpdGggaGlnaCBwYXJlbnRhbCBpbnZvbHZlbWVudCBoYXZlIGhpZ2hlciBhdmVyYWdlIGV4YW0gc2NvcmVzLCBmb2xsb3dlZCBieSBzdHVkZW50cyB3aXRoIG1lZGl1bSBwYXJlbnRhbCBpbnZvbHZlbWVudCwgYW5kIHN0dWRlbnRzIHdpdGggbG93IHBhcmVudGFsIGludm9sdmVtZW50IGhhdmUgdGhlIGxvd2VzdCBhdmVyYWdlIGV4YW0gc2NvcmVzLg0KDQojIyMgRGlzdHJpYnV0aW9uIG9mIEZpbmFsIEV4YW0gU2NvcmVzIChBY2Nlc3NfdG9fUmVzb3VyY2VzIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcy4gV2Ugd2lsbCBjcmVhdGUgYSBib3hwbG90IHRvIGNvbXBhcmUgdGhlIHNjb3JlcyBvZiBzdHVkZW50cyB3aXRoIGRpZmZlcmVudCBsZXZlbHMgb2YgYWNjZXNzIHRvIHJlc291cmNlcy4NCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmhpZ2hfYWNjZXNzX3RvX3Jlc291cmNlc19leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiSGlnaCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkhpZ2giKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbG93X2FjY2Vzc190b19yZXNvdXJjZXNfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTG93IiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTG93Iikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGFjY2VzcyB0byByZXNvdXJjZXMNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfYWNjZXNzX3RvX3Jlc291cmNlc19leGFtX3Njb3JlLCBtYWluID0gIkhpZ2ggQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXNfZXhhbV9zY29yZSwgbWFpbiA9ICJNZWRpdW0gQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobG93X2FjY2Vzc190b19yZXNvdXJjZXNfZXhhbV9zY29yZSwgbWFpbiA9ICJMb3cgQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KcGxvdChkZW5zaXR5KGxvd19hY2Nlc3NfdG9fcmVzb3VyY2VzX2V4YW1fc2NvcmUpLCBtYWluID0gIkxvdyBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiKQ0KcGxvdChkZW5zaXR5KG1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2V4YW1fc2NvcmUpLCBtYWluID0gIk1lZGl1bSBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiKQ0KcGxvdChkZW5zaXR5KGhpZ2hfYWNjZXNzX3RvX3Jlc291cmNlc19leGFtX3Njb3JlKSwgbWFpbiA9ICJIaWdoIEFjY2VzcyB0byBSZXNvdXJjZXMiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIpDQpgYGANCg0KLSAqKkhpZ2ggQWNjZXNzIHRvIFJlc291cmNlcyoqOiBUaGUgZGlzdHJpYnV0aW9uIGlzIHBvc2l0aXZlbHkgc2tld2VkLCB3aXRoIG1vc3Qgc2NvcmVzIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDgwYCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuDQotICoqTWVkaXVtIEFjY2VzcyB0byBSZXNvdXJjZXMqKjogVGhlIGRpc3RyaWJ1dGlvbiBpcyBzaW1pbGFyIHRvIGhpZ2ggYWNjZXNzIHRvIHJlc291cmNlcywgd2l0aCBtb3N0IHNjb3JlcyBiZXR3ZWVuICoqYDYwYCoqIGFuZCAqKmA4MGAqKi4gVGhlcmUgYXJlIGEgZmV3IG91dGxpZXJzIGFib3ZlIDgwLCBpbmRpY2F0aW5nIGV4Y2VwdGlvbmFsIHBlcmZvcm1hbmNlLg0KLSAqKkxvdyBBY2Nlc3MgdG8gUmVzb3VyY2VzKio6IFRoZSBkaXN0cmlidXRpb24gYXBwZWFycyB0byBiZSBtb3JlIHNwcmVhZCBvdXQgY29tcGFyZWQgdG8gaGlnaCBhbmQgbWVkaXVtIGFjY2VzcyB0byByZXNvdXJjZXMsIHdpdGggc2NvcmVzIHJhbmdpbmcgZnJvbSAqKmA1NWAqKiB0byAqKmA3NWAqKi4gVGhlcmUgYXJlIGFwcGVhcnMgdG8gYmUgc21hbGwgdGFpbCBvZiBzdHVkZW50cyBzY29yaW5nIGhpZ2hlci4NCg0KYGBge3J9DQojIFNoYXBpcm8tV2lsayB0ZXN0IGZvciBub3JtYWxpdHkNCnNoYXBpcm8udGVzdChoaWdoX2FjY2Vzc190b19yZXNvdXJjZXNfZXhhbV9zY29yZSkNCnNoYXBpcm8udGVzdChtZWRpdW1fYWNjZXNzX3RvX3Jlc291cmNlc19leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KGxvd19hY2Nlc3NfdG9fcmVzb3VyY2VzX2V4YW1fc2NvcmUpDQpgYGANCg0KVGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3dzIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgZmluYWwgZXhhbSBzY29yZXMgZm9yIHN0dWRlbnRzIHdpdGggaGlnaCwgbWVkaXVtLCBhbmQgbG93IGFjY2VzcyB0byByZXNvdXJjZXMgYXJlIG5vdCBub3JtYWwsIHdpdGggcC12YWx1ZXMgbGVzcyB0aGFuIDAuMDUuDQoNCk5leHQsIHdlIHdpbGwgdXNlIEtydXNrYWwtV2FsbGlzIHRlc3QgdG8gY2hlY2sgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGlzIGRpZmZlcmVudCBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBhY2Nlc3MgdG8gcmVzb3VyY2VzDQpzdW1tYXJ5KGhpZ2hfYWNjZXNzX3RvX3Jlc291cmNlc19leGFtX3Njb3JlKQ0Kc3VtbWFyeShtZWRpdW1fYWNjZXNzX3RvX3Jlc291cmNlc19leGFtX3Njb3JlKQ0Kc3VtbWFyeShsb3dfYWNjZXNzX3RvX3Jlc291cmNlc19leGFtX3Njb3JlKQ0KDQojIEtydXNrYWwtV2FsbGlzIHRlc3QgZm9yIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGFjY2VzcyB0byByZXNvdXJjZXMNCmtydXNrYWwudGVzdChFeGFtX1Njb3JlIH4gQWNjZXNzX3RvX1Jlc291cmNlcywgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcywgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgYWNjZXNzIHRvIHJlc291cmNlcyBoYXMgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIGZpbmFsIGV4YW0gc2NvcmVzLiBGcm9tIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MsIHdlIGNhbiBzZWUgdGhhdCBzdHVkZW50cyB3aXRoIGhpZ2ggYWNjZXNzIHRvIHJlc291cmNlcyBoYXZlIGhpZ2hlciBhdmVyYWdlIGV4YW0gc2NvcmVzLCBmb2xsb3dlZCBieSBzdHVkZW50cyB3aXRoIG1lZGl1bSBhY2Nlc3MgdG8gcmVzb3VyY2VzLCBhbmQgc3R1ZGVudHMgd2l0aCBsb3cgYWNjZXNzIHRvIHJlc291cmNlcyBoYXZlIHRoZSBsb3dlc3QgYXZlcmFnZSBleGFtIHNjb3Jlcy4NCg0KIyMjIERpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyAoRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLiBXZSB3aWxsIGNyZWF0ZSBhIGJveHBsb3QgdG8gY29tcGFyZSB0aGUgc2NvcmVzIG9mIHN0dWRlbnRzIHdobyBwYXJ0aWNpcGF0ZSBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcyBhbmQgdGhvc2Ugd2hvIGRvIG5vdC4NCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCnBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiWWVzIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIlllcyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJZZXMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgQm94cGxvdCBvZiBmaW5hbCBleGFtIHNjb3JlcyBieSBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcw0KYm94cGxvdChzdHVkZW50X2RhdGEkRXhhbV9TY29yZSB+IHN0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcywgbWFpbiA9ICJGaW5hbCBFeGFtIFNjb3JlcyBieSBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyIsIHhsYWIgPSAiRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMiLCB5bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KVGhlIGJveHBsb3Qgc2hvd3MgdGhhdCBzdHVkZW50cyB3aG8gcGFydGljaXBhdGUgaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMgdGVuZCB0byBoYXZlIGhpZ2hlciBmaW5hbCBleGFtIHNjb3JlcyBjb21wYXJlZCB0byB0aG9zZSB3aG8gZG8gbm90LiBOb3cgd2Ugd2lsbCB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzY29yZXMgZm9yIGJvdGggZ3JvdXBzIHVzaW5nIGhpc3RvZ3JhbXMuDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChwYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfZXhhbV9zY29yZSwgbWFpbiA9ICJFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QoZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9leGFtX3Njb3JlLCBtYWluID0gIk5vIEV4dHJhY3VycmljdWxhciBBY3Rpdml0aWVzIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYGBgDQoNCi0gKipFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyoqOiBUaGUgZGlzdHJpYnV0aW9uIGlzIHBvc2l0aXZlbHkgc2tld2VkLCB3aXRoIG1vc3Qgc2NvcmVzIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDgwYCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuDQotICoqTm8gRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMqKjogVGhlIGRpc3RyaWJ1dGlvbiBpcyBzaW1pbGFyIHRvIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLCB3aXRoIG1vc3Qgc2NvcmVzIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDc1YCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuDQoNCg0KYGBge3J9DQojIFNoYXBpcm8tV2lsayB0ZXN0IGZvciBub3JtYWxpdHkNCnNoYXBpcm8udGVzdChwYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfZXhhbV9zY29yZSkNCnNoYXBpcm8udGVzdChkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2V4YW1fc2NvcmUpDQpgYGANCg0KVGhlIFNoYXBpcm8tV2lsayB0ZXN0IGNvbmZpcm1zIHRoYXQgYm90aCBkaXN0cmlidXRpb25zIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGZvciBzdHVkZW50cyB3aG8gcGFydGljaXBhdGUgaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMgYW5kIHRob3NlIHdobyBkbyBub3QgaXMgbm90IG5vcm1hbCwgd2l0aCBwLXZhbHVlcyBsZXNzIHRoYW4gMC4wNS4NCg0KTmV4dCwgd2Ugd2lsbCB1c2UgV2lsY294b24gcmFuay1zdW0gdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMuDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQpzdW1tYXJ5KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9leGFtX3Njb3JlKQ0Kc3VtbWFyeShkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2V4YW1fc2NvcmUpDQoNCiMgV2lsY294b24gcmFuay1zdW0gdGVzdCBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMNCndpbGNveC50ZXN0KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9leGFtX3Njb3JlLCBkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2V4YW1fc2NvcmUpDQpgYGANCg0KVGhlIFdpbGNveG9uIHJhbmstc3VtIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIGZpbmFsIGV4YW0gc2NvcmVzLg0KDQojIyMgRGlzdHJpYnV0aW9uIG9mIEZpbmFsIEV4YW0gU2NvcmVzIChNb3RpdmF0aW9uX0xldmVsIENhdGVnb3J5KQ0KDQpOZXh0IHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBtb3RpdmF0aW9uIGxldmVscy4gV2Ugd2lsbCBjcmVhdGUgYSBoaXN0b2dyYW0gdG8gY29tcGFyZSB0aGUgc2NvcmVzIG9mIHN0dWRlbnRzIHdpdGggZGlmZmVyZW50IG1vdGl2YXRpb24gbGV2ZWxzLg0KYGBge3J9DQojIFNtYXBsZSBEYXRhDQpoaWdoX21vdGl2YXRpb25fZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiSGlnaCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkhpZ2giKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJIaWdoIikqc2FtcGxlX2ZyYWN0aW9uKSldDQptZWRpdW1fbW90aXZhdGlvbl9leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJNZWRpdW0iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJNZWRpdW0iKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJNZWRpdW0iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmxvd19tb3RpdmF0aW9uX2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkxvdyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkxvdyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIEhpc3RvZ3JhbSBvZiBmaW5hbCBleGFtIHNjb3JlcyBieSBtb3RpdmF0aW9uIGxldmVsDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX21vdGl2YXRpb25fZXhhbV9zY29yZSwgbWFpbiA9ICJIaWdoIE1vdGl2YXRpb24gTGV2ZWwiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV9tb3RpdmF0aW9uX2V4YW1fc2NvcmUsIG1haW4gPSAiTWVkaXVtIE1vdGl2YXRpb24gTGV2ZWwiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGxvd19tb3RpdmF0aW9uX2V4YW1fc2NvcmUsIG1haW4gPSAiTG93IE1vdGl2YXRpb24gTGV2ZWwiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KLSAqKkhpZ2ggTW90aXZhdGlvbiBMZXZlbCoqOiBFeGFtIHNjb3JlcyBhcmUgbW9zdGx5IGNvbmNlbnRyYXRlZCBiZXR3ZWVuICoqYDYwYCoqIGFuZCAqKmA3NWAqKiwgaW5kaWNhdGluZyB0aGF0IHN0dWRlbnRzIHdpdGggaGlnaCBtb3RpdmF0aW9uIGNvbnNpc3RlbnRseSBwZXJmb3JtIHdlbGwuIFRoZSBwZWFrIGZyZXF1ZW5jeSBvY2N1cnMgYXQgdGhlIG1pZGRsZSBvZiB0aGlzIHJhbmdlLg0KLSAqKk1lZGl1bSBNb3RpdmF0aW9uIExldmVsKio6IFNjb3JlcyBhcmUgYWxzbyBjbHVzdGVyZWQgYmV0d2VlbiAqKmA2MGAqKiBhbmQgKipgODBgKiosIGJ1dCB3aXRoIHNsaWdodGx5IGxlc3MgdmFyaWFiaWxpdHkgY29tcGFyZWQgdG8gdGhlIGhpZ2gtbW90aXZhdGlvbiBncm91cC4gVGhlcmUgYXBwZWFycyB0byBiZSBhIHNtYWxsIHRhaWwgb2Ygc3R1ZGVudHMgc2NvcmluZyBoaWdoZXIuDQotICoqTG93IE1vdGl2YXRpb24gTGV2ZWwqKjogU2NvcmVzIGFyZSBsZXNzIHdpZGVseSBzcHJlYWQgYmV0d2VlbiAqKmA2MGAqKiBhbmQgKipgNzVgKiosIHdpdGggc29tZSBvdXRsaWVycyBzY29yaW5nIG11Y2ggaGlnaGVyLg0KDQpgYGB7cn0NCiMgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eQ0Kc2hhcGlyby50ZXN0KGhpZ2hfbW90aXZhdGlvbl9leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KG1lZGl1bV9tb3RpdmF0aW9uX2V4YW1fc2NvcmUpDQpzaGFwaXJvLnRlc3QobG93X21vdGl2YXRpb25fZXhhbV9zY29yZSkNCmBgYA0KDQpBbGwgdGVzdHMgc2hvdyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgZm9yIHN0dWRlbnRzIHdpdGggaGlnaCwgbWVkaXVtLCBhbmQgbG93IG1vdGl2YXRpb24gbGV2ZWxzIGlzIG5vdCBub3JtYWwsIHdpdGggcC12YWx1ZXMgbGVzcyB0aGFuIDAuMDUuDQoNCk5vdyB3ZSB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIG1vdGl2YXRpb24gbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBtb3RpdmF0aW9uIGxldmVsDQpzdW1tYXJ5KGhpZ2hfbW90aXZhdGlvbl9leGFtX3Njb3JlKQ0Kc3VtbWFyeShtZWRpdW1fbW90aXZhdGlvbl9leGFtX3Njb3JlKQ0Kc3VtbWFyeShsb3dfbW90aXZhdGlvbl9leGFtX3Njb3JlKQ0KDQojIEtydXNrYWwtV2FsbGlzIHRlc3QgZm9yIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IG1vdGl2YXRpb24gbGV2ZWwNCmtydXNrYWwudGVzdChFeGFtX1Njb3JlIH4gTW90aXZhdGlvbl9MZXZlbCwgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gbW90aXZhdGlvbiBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGxlc3MgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IG1vdGl2YXRpb24gbGV2ZWxzIGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIGZpbmFsIGV4YW0gc2NvcmVzLiBGcm9tIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MsIHdlIGNhbiBzZWUgdGhhdCBzdHVkZW50cyB3aXRoIGhpZ2ggbW90aXZhdGlvbiBoYXZlIGhpZ2hlciBhdmVyYWdlIGV4YW0gc2NvcmVzLCBmb2xsb3dlZCBieSBzdHVkZW50cyB3aXRoIG1lZGl1bSBtb3RpdmF0aW9uLCBhbmQgc3R1ZGVudHMgd2l0aCBsb3cgbW90aXZhdGlvbiBoYXZlIHRoZSBsb3dlc3QgYXZlcmFnZSBleGFtIHNjb3Jlcy4NCg0KDQoNCiMjIyBEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMgKEludGVybmV0X0FjY2VzcyBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIGludGVybmV0IGFjY2Vzcy4gV2Ugd2lsbCBjcmVhdGUgYSBib3hwbG90IHRvIGNvbXBhcmUgdGhlIHNjb3JlcyBvZiBzdHVkZW50cyB3aXRoIGFuZCB3aXRob3V0IGludGVybmV0IGFjY2Vzcy4NCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmludGVybmV0X2FjY2Vzc19leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiWWVzIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkSW50ZXJuZXRfQWNjZXNzID09ICJZZXMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm5vX2ludGVybmV0X2FjY2Vzc19leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkSW50ZXJuZXRfQWNjZXNzID09ICJObyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiTm8iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBIaXN0b2dyYW0gb2YgZmluYWwgZXhhbSBzY29yZXMgYnkgaW50ZXJuZXQgYWNjZXNzDQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChpbnRlcm5ldF9hY2Nlc3NfZXhhbV9zY29yZSwgbWFpbiA9ICJJbnRlcm5ldCBBY2Nlc3MiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG5vX2ludGVybmV0X2FjY2Vzc19leGFtX3Njb3JlLCBtYWluID0gIk5vIEludGVybmV0IEFjY2VzcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQotICoqSW50ZXJuZXQgQWNjZXNzKio6IFRoZSBkaXN0cmlidXRpb24gYXBwZWFycyBwb3NpdGl2ZWx5IHNrZXdlZCwgd2l0aCBtb3N0IHNjb3JlcyBjbHVzdGVyZWQgYmV0d2VlbiAqKmA2MGAqKiBhbmQgKipgODBgKiouIFRoZSBtb2RlIG9yIG1vc3QgZnJlcXVlbnQgc2NvcmUgc2VlbXMgdG8gZmFsbCBhcm91bmQgKipgNjUtNzBgKiouIFRoZXJlIGFwcGVhcnMgdG8gYmUgZmV3IG91dGxpZXJzIHNjb3JpbmcgYWJvdmUgKipgNzVgKiouDQotICoqTm8gSW50ZXJuZXQgQWNjZXNzKio6IFRoaXMgZGlzdHJpYnV0aW9uIGlzIHNsaWdodGx5IHNrZXdlZCwgd2l0aCBzY29yZXMgcHJpbWFyaWx5IGNsdXN0ZXJlZCBhcm91bmQgKipgNjBgKiogYW5kIGV4dGVuZGluZyB0b3dhcmQgKipgNzVgKiouIFRoZXJlIGFyZSBzb21lIG91dGxpZXJzIGJleW9uZCAqKmA3NWAqKi4gVGhlIGhpZ2hlc3QgZnJlcXVlbmN5IG9jY3VycyBhcm91bmQgKipgNjVgKiouIFNjb3JlcyBhcmUgbW9yZSB3aWRlbHkgZGlzdHJpYnV0ZWQgY29tcGFyZWQgdG8gdGhlIF9fSW50ZXJuZXQgQWNjZXNzX18gZ3JvdXAuDQoNCmBgYHtyfQ0KIyBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzaGFwaXJvLnRlc3QoaW50ZXJuZXRfYWNjZXNzX2V4YW1fc2NvcmUpDQpzaGFwaXJvLnRlc3Qobm9faW50ZXJuZXRfYWNjZXNzX2V4YW1fc2NvcmUpDQpgYGANCg0KVGhlIFNoYXBpcm8tV2lsayB0ZXN0IGNvbmZpcm1zIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3Igc3R1ZGVudHMgd2l0aCBhbmQgd2l0aG91dCBpbnRlcm5ldCBhY2Nlc3MgaXMgbm90IG5vcm1hbCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuDQoNCk5leHQsIHdlIHVzZSBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBpcyBkaWZmZXJlbnQgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBpbnRlcm5ldCBhY2Nlc3MNCnN1bW1hcnkoaW50ZXJuZXRfYWNjZXNzX2V4YW1fc2NvcmUpDQpzdW1tYXJ5KG5vX2ludGVybmV0X2FjY2Vzc19leGFtX3Njb3JlKQ0KDQojIFdpbGNveG9uIHJhbmstc3VtIHRlc3QgZm9yIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGludGVybmV0IGFjY2Vzcw0Kd2lsY294LnRlc3QoaW50ZXJuZXRfYWNjZXNzX2V4YW1fc2NvcmUsIG5vX2ludGVybmV0X2FjY2Vzc19leGFtX3Njb3JlKQ0KYGBgDQoNClRoZSBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBpbnRlcm5ldCBhY2Nlc3MgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgZmluYWwgZXhhbSBzY29yZXMuDQoNCiMjIyBEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMgKEZhbWlseV9JbmNvbWUgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KbG93X2luY29tZV9leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm1lZGl1bV9pbmNvbWVfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTWVkaXVtIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTWVkaXVtIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpoaWdoX2luY29tZV9leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiSGlnaCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIkhpZ2giKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBIaXN0b2dyYW0gb2YgZmluYWwgZXhhbSBzY29yZXMgYnkgZmFtaWx5IGluY29tZQ0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QobG93X2luY29tZV9leGFtX3Njb3JlLCBtYWluID0gIkxvdyBGYW1pbHkgSW5jb21lIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1faW5jb21lX2V4YW1fc2NvcmUsIG1haW4gPSAiTWVkaXVtIEZhbWlseSBJbmNvbWUiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGhpZ2hfaW5jb21lX2V4YW1fc2NvcmUsIG1haW4gPSAiSGlnaCBGYW1pbHkgSW5jb21lIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYGBgDQoNCi0gKipMb3cgRmFtaWx5IEluY29tZSoqOiBUaGUgZGlzdHJpYnV0aW9uIGlzIHBvc2l0aXZlbHkgc2tld2VkLCB3aXRoIG1vc3Qgc2NvcmVzIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDc1YCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuDQotICoqTWVkaXVtIEZhbWlseSBJbmNvbWUqKjogVGhlIGRpc3RyaWJ1dGlvbiBpcyBzaW1pbGFyIHRvIGxvdyBmYW1pbHkgaW5jb21lLCB3aXRoIG1vc3Qgc2NvcmVzIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDc1YCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuDQotICoqSGlnaCBGYW1pbHkgSW5jb21lKio6IFRoZSBkaXN0cmlidXRpb24gaXMgcG9zaXRpdmVseSBza2V3ZWQsIGFuZCBpdCBhcHBlYXJzIHRvIGJlIG1vcmUgc3ByZWFkIG91dCBjb21wYXJlZCB0byBsb3cgYW5kIG1lZGl1bSBmYW1pbHkgaW5jb21lLCB3aXRoIHNjb3JlcyByYW5naW5nIGZyb20gKipgNTVgKiogdG8gKipgODBgKiouIFRoZXJlIGFyZSBhIGZldyBvdXRsaWVycyBhYm92ZSA4MCwgaW5kaWNhdGluZyBleGNlcHRpb25hbCBwZXJmb3JtYW5jZS4NCg0KYGBge3J9DQojIFNoYXBpcm8tV2lsayB0ZXN0IGZvciBub3JtYWxpdHkNCnNoYXBpcm8udGVzdChsb3dfaW5jb21lX2V4YW1fc2NvcmUpDQpzaGFwaXJvLnRlc3QobWVkaXVtX2luY29tZV9leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KGhpZ2hfaW5jb21lX2V4YW1fc2NvcmUpDQpgYGANClRoZSBTaGFwaXJvLVdpbGsgdGVzdCBjb25maXJtcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgZm9yIGFsbCBzdHVkZW50cyBpcyBub3Qgbm9ybWFsLCB3aXRoIGEgcC12YWx1ZSB0aGF0IGlzIGxlc3MgdGhhbiAwLjA1Lg0KDQpXZSBub3cgdXNlIEtydXNrYWwtV2FsbGlzIHRlc3QgdG8gY2hlY2sgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGlzIGRpZmZlcmVudCBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscy4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgZmFtaWx5IGluY29tZQ0Kc3VtbWFyeShoaWdoX2luY29tZV9leGFtX3Njb3JlKQ0Kc3VtbWFyeShtZWRpdW1faW5jb21lX2V4YW1fc2NvcmUpDQpzdW1tYXJ5KGxvd19pbmNvbWVfZXhhbV9zY29yZSkNCg0KIyBLcnVza2FsLVdhbGxpcyB0ZXN0IGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBmYW1pbHkgaW5jb21lDQprcnVza2FsLnRlc3QoRXhhbV9TY29yZSB+IEZhbWlseV9JbmNvbWUsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydXNrYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIGZhbWlseSBpbmNvbWUgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBmYW1pbHkgaW5jb21lIGhhcyBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgZmluYWwgZXhhbSBzY29yZXMuIEZyb20gdGhlIHN1bW1hcnkgc3RhdGlzdGljcywgd2UgY2FuIHNlZSB0aGF0IHN0dWRlbnRzIHdpdGggaGlnaCBmYW1pbHkgaW5jb21lIGhhdmUgaGlnaGVyIGF2ZXJhZ2UgZXhhbSBzY29yZXMsIGZvbGxvd2VkIGJ5IHN0dWRlbnRzIHdpdGggbWVkaXVtIGZhbWlseSBpbmNvbWUsIGFuZCBzdHVkZW50cyB3aXRoIGxvdyBmYW1pbHkgaW5jb21lIGhhdmUgdGhlIGxvd2VzdCBhdmVyYWdlIGV4YW0gc2NvcmVzLg0KDQojIyMgRGlzdHJpYnV0aW9uIG9mIEZpbmFsIEV4YW0gU2NvcmVzIChUZWFjaGVyX1F1YWxpdHkgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIGRhdGENCmhpZ2hfdGVhY2hlcl9xdWFsaXR5X2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiSGlnaCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiSGlnaCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiSGlnaCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTWVkaXVtIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJNZWRpdW0iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmxvd190ZWFjaGVyX3F1YWxpdHlfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkxvdyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTG93Iikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IHRlYWNoZXIgcXVhbGl0eQ0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QoaGlnaF90ZWFjaGVyX3F1YWxpdHlfZXhhbV9zY29yZSwgbWFpbiA9ICJIaWdoIFRlYWNoZXIgUXVhbGl0eSIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9leGFtX3Njb3JlLCBtYWluID0gIk1lZGl1bSBUZWFjaGVyIFF1YWxpdHkiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGxvd190ZWFjaGVyX3F1YWxpdHlfZXhhbV9zY29yZSwgbWFpbiA9ICJMb3cgVGVhY2hlciBRdWFsaXR5IiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYGBgDQoNCi0gKipIaWdoIFRlYWNoZXIgUXVhbGl0eSoqOiBUaGUgZGlzdHJpYnV0aW9uIGlzIHBvc2l0aXZlbHkgc2tld2VkLCB3aXRoIG1vc3Qgc2NvcmVzIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDc1YCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuDQotICoqTWVkaXVtIFRlYWNoZXIgUXVhbGl0eSoqOiBUaGUgZGlzdHJpYnV0aW9uIGlzIHNpbWlsYXIgdG8gaGlnaCB0ZWFjaGVyIHF1YWxpdHksIHdpdGggbW9zdCBzY29yZXMgYmV0d2VlbiAqKmA2MGAqKiBhbmQgKipgNzVgKiouIFRoZXJlIGFyZSBhIGZldyBvdXRsaWVycyBhYm92ZSA4MCwgaW5kaWNhdGluZyBleGNlcHRpb25hbCBwZXJmb3JtYW5jZS4NCi0gKipMb3cgVGVhY2hlciBRdWFsaXR5Kio6IFRoZSBkaXN0cmlidXRpb24gaXMgcG9zaXRpdmVseSBza2V3ZWQsIHdpdGggc2NvcmVzIHJhbmdpbmcgZnJvbSAqKmA1NWAqKiB0byAqKmA3NWAqKi4gVGhlcmUgYXJlIGEgZmV3IG91dGxpZXJzIGFib3ZlIDgwLCBpbmRpY2F0aW5nIGV4Y2VwdGlvbmFsIHBlcmZvcm1hbmNlLg0KDQpgYGB7cn0NCiMgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eQ0Kc2hhcGlyby50ZXN0KGhpZ2hfdGVhY2hlcl9xdWFsaXR5X2V4YW1fc2NvcmUpDQpzaGFwaXJvLnRlc3QobWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KGxvd190ZWFjaGVyX3F1YWxpdHlfZXhhbV9zY29yZSkNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3QgY29uZmlybXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGZvciBhbGwgc3R1ZGVudHMgaXMgbm90IG5vcm1hbCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuDQoNCldlIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIHRlYWNoZXIgcXVhbGl0eSBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IHRlYWNoZXIgcXVhbGl0eQ0Kc3VtbWFyeShoaWdoX3RlYWNoZXJfcXVhbGl0eV9leGFtX3Njb3JlKQ0Kc3VtbWFyeShtZWRpdW1fdGVhY2hlcl9xdWFsaXR5X2V4YW1fc2NvcmUpDQpzdW1tYXJ5KGxvd190ZWFjaGVyX3F1YWxpdHlfZXhhbV9zY29yZSkNCg0KIyBLcnVza2FsLVdhbGxpcyB0ZXN0IGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSB0ZWFjaGVyIHF1YWxpdHkNCmtydXNrYWwudGVzdChFeGFtX1Njb3JlIH4gVGVhY2hlcl9RdWFsaXR5LCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0ZWFjaGVyIHF1YWxpdHkgaGFzIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBmaW5hbCBleGFtIHNjb3Jlcy4gRnJvbSB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzLCB3ZSBjYW4gc2VlIHRoYXQgc3R1ZGVudHMgd2l0aCBoaWdoIHRlYWNoZXIgcXVhbGl0eSBoYXZlIGhpZ2hlciBhdmVyYWdlIGV4YW0gc2NvcmVzLCBmb2xsb3dlZCBieSBzdHVkZW50cyB3aXRoIGxvdyB0ZWFjaGVyIHF1YWxpdHksIGFuZCBzdHVkZW50cyB3aXRoIG1lZGl1bSB0ZWFjaGVyIHF1YWxpdHkgaGF2ZSB0aGUgbG93ZXN0IGF2ZXJhZ2UgZXhhbSBzY29yZXMuDQoNCiMjIyBEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMgKFNjaG9vbF9UeXBlIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gc2Nob29sIHR5cGUuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgZGF0YQ0KcHVibGljX3NjaG9vbF9leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRTY2hvb2xfVHlwZSA9PSAiUHVibGljIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlB1YmxpYyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQdWJsaWMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCnByaXZhdGVfc2Nob29sX2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQcml2YXRlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlByaXZhdGUiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRTY2hvb2xfVHlwZSA9PSAiUHJpdmF0ZSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIEhpc3RvZ3JhbSBvZiBmaW5hbCBleGFtIHNjb3JlcyBieSBzY2hvb2wgdHlwZQ0KcGFyKG1mcm93ID0gYygxLCAyKSkNCmhpc3QocHVibGljX3NjaG9vbF9leGFtX3Njb3JlLCBtYWluID0gIlB1YmxpYyBTY2hvb2wiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KHByaXZhdGVfc2Nob29sX2V4YW1fc2NvcmUsIG1haW4gPSAiUHJpdmF0ZSBTY2hvb2wiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KLSAqKlB1YmxpYyBTY2hvb2wqKjogVGhlIGRpc3RyaWJ1dGlvbiBpcyBwb3NpdGl2ZWx5IHNrZXdlZCwgd2l0aCBtb3N0IHNjb3JlcyBiZXR3ZWVuICoqYDYwYCoqIGFuZCAqKmA3NWAqKi4gVGhlcmUgYXJlIGEgZmV3IG91dGxpZXJzIGFib3ZlIDgwLCBpbmRpY2F0aW5nIGV4Y2VwdGlvbmFsIHBlcmZvcm1hbmNlLiBUaGUgbW9kZSBvciBtb3N0IGZyZXF1ZW50IHNjb3JlIHNlZW1zIHRvIGZhbGwgYXJvdW5kICoqYDY1LTcwYCoqLg0KLSAqKlByaXZhdGUgU2Nob29sKio6IFRoZSBkaXN0cmlidXRpb24gaXMgc2ltaWxhciB0byBwdWJsaWMgc2Nob29sLCB3aXRoIG1vc3Qgc2NvcmVzIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDc1YCoqLiBUaGVyZSBhcmUgYSBmZXcgb3V0bGllcnMgYWJvdmUgODAsIGluZGljYXRpbmcgZXhjZXB0aW9uYWwgcGVyZm9ybWFuY2UuIFRoZSBtb2RlIG9yIG1vc3QgZnJlcXVlbnQgc2NvcmUgc2VlbXMgdG8gZmFsbCBhcm91bmQgKipgNjUtNzBgKiouDQoNCmBgYHtyfQ0KIyBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzaGFwaXJvLnRlc3QocHVibGljX3NjaG9vbF9leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KHByaXZhdGVfc2Nob29sX2V4YW1fc2NvcmUpDQpgYGANCg0KVGhlIFNoYXBpcm8tV2lsayB0ZXN0IGNvbmZpcm1zIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3Igc3R1ZGVudHMgaW4gcHVibGljIGFuZCBwcml2YXRlIHNjaG9vbHMgaXMgbm90IG5vcm1hbCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuDQoNCldlIG5vdyB1c2UgV2lsY294b24gcmFuay1zdW0gdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIHNjaG9vbCB0eXBlLg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBzY2hvb2wgdHlwZQ0Kc3VtbWFyeShwdWJsaWNfc2Nob29sX2V4YW1fc2NvcmUpDQpzdW1tYXJ5KHByaXZhdGVfc2Nob29sX2V4YW1fc2NvcmUpDQoNCiMgV2lsY294b24gcmFuay1zdW0gdGVzdCBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgc2Nob29sIHR5cGUNCndpbGNveC50ZXN0KHB1YmxpY19zY2hvb2xfZXhhbV9zY29yZSwgcHJpdmF0ZV9zY2hvb2xfZXhhbV9zY29yZSkNCmBgYA0KDQpUaGUgV2lsY294b24gcmFuay1zdW0gdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIHNjaG9vbCB0eXBlLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBzY2hvb2wgdHlwZSBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBmaW5hbCBleGFtIHNjb3Jlcy4NCg0KIyMjIERpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyAoUGVlcl9JbmZsdWVuY2UgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgZGF0YQ0KcG9zaXRpdmVfcGVlcl9pbmZsdWVuY2VfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZV9leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmVnYXRpdmUiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmVnYXRpdmUiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmVnYXRpdmUiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm5ldXRyYWxfcGVlcl9pbmZsdWVuY2VfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIk5ldXRyYWwiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmV1dHJhbCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZXV0cmFsIikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IHBlZXIgaW5mbHVlbmNlDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChwb3NpdGl2ZV9wZWVyX2luZmx1ZW5jZV9leGFtX3Njb3JlLCBtYWluID0gIkhpZ2ggUGVlciBJbmZsdWVuY2UiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG5lZ2F0aXZlX3BlZXJfaW5mbHVlbmNlX2V4YW1fc2NvcmUsIG1haW4gPSAiTWVkaXVtIFBlZXIgSW5mbHVlbmNlIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChuZXV0cmFsX3BlZXJfaW5mbHVlbmNlX2V4YW1fc2NvcmUsIG1haW4gPSAiTG93IFBlZXIgSW5mbHVlbmNlIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYGBgDQoNClRoZSBkaXN0cmlidXRpb25zIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscyBhcHBlYXIgdG8gYmUgdGhlIHNhbWUgYWNyb3NzIGFsbCBjYXRlZ29yaWVzLiBUaGUgc2NvcmVzIGFwcGVhcnMgdG8gYmUgY29uY2VudHJhdGVkIGJldHdlZW4gKipgNjBgKiogYW5kICoqYDc1YCoqIGZvciBhbGwgcGVlciBpbmZsdWVuY2UgbGV2ZWxzLCB3aXRoIGEgZmV3IG91dGxpZXJzIHNjb3JpbmcgYWJvdmUgODAuDQoNCmBgYHtyfQ0KIyBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzaGFwaXJvLnRlc3QocG9zaXRpdmVfcGVlcl9pbmZsdWVuY2VfZXhhbV9zY29yZSkNCnNoYXBpcm8udGVzdChuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZV9leGFtX3Njb3JlKQ0Kc2hhcGlyby50ZXN0KG5ldXRyYWxfcGVlcl9pbmZsdWVuY2VfZXhhbV9zY29yZSkNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3QgY29uZmlybXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGZvciBhbGwgc3R1ZGVudHMgaXMgbm90IG5vcm1hbCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuDQoNCldlIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscy4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgcGVlciBpbmZsdWVuY2UNCnN1bW1hcnkocG9zaXRpdmVfcGVlcl9pbmZsdWVuY2VfZXhhbV9zY29yZSkNCnN1bW1hcnkobmVnYXRpdmVfcGVlcl9pbmZsdWVuY2VfZXhhbV9zY29yZSkNCnN1bW1hcnkobmV1dHJhbF9wZWVyX2luZmx1ZW5jZV9leGFtX3Njb3JlKQ0KDQojIEtydXNrYWwtV2FsbGlzIHRlc3QgZm9yIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IHBlZXIgaW5mbHVlbmNlDQprcnVza2FsLnRlc3QoRXhhbV9TY29yZSB+IFBlZXJfSW5mbHVlbmNlLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGxlc3MgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHBlZXIgaW5mbHVlbmNlIGhhcyBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgZmluYWwgZXhhbSBzY29yZXMuIEZyb20gdGhlIHN1bW1hcnkgc3RhdGlzdGljcywgd2UgY2FuIHNlZSB0aGF0IHN0dWRlbnRzIHdpdGggcG9zaXRpdmUgcGVlciBpbmZsdWVuY2UgaGF2ZSBoaWdoZXIgYXZlcmFnZSBleGFtIHNjb3JlcywgZm9sbG93ZWQgYnkgc3R1ZGVudHMgd2l0aCBuZXV0cmFsIHBlZXIgaW5mbHVlbmNlLCBhbmQgc3R1ZGVudHMgd2l0aCBuZWdhdGl2ZSBwZWVyIGluZmx1ZW5jZSBoYXZlIHRoZSBsb3dlc3QgYXZlcmFnZSBleGFtIHNjb3Jlcy4NCg0KIyMjIERpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyAoTGVhcm5pbmdfRGlzYWJpbGl0aWVzIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0aWVzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIGRhdGENCmxlYXJuaW5nX2Rpc2FiaWxpdGllc19leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJExlYXJuaW5nX0Rpc2FiaWxpdGllcyA9PSAiWWVzIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJZZXMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllc19leGFtX3Njb3JlIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJObyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJExlYXJuaW5nX0Rpc2FiaWxpdGllcyA9PSAiTm8iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBIaXN0b2dyYW0gb2YgZmluYWwgZXhhbSBzY29yZXMgYnkgbGVhcm5pbmcgZGlzYWJpbGl0aWVzDQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChsZWFybmluZ19kaXNhYmlsaXRpZXNfZXhhbV9zY29yZSwgbWFpbiA9ICJMZWFybmluZyBEaXNhYmlsaXRpZXMiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllc19leGFtX3Njb3JlLCBtYWluID0gIk5vIExlYXJuaW5nIERpc2FiaWxpdGllcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQotICoqTGVhcm5pbmcgRGlzYWJpbGl0aWVzKio6IFNjb3JlcyBhcmUgbmFycm93bHkgZGlzdHJpYnV0ZWQsIHByaW1hcmlseSBjbHVzdGVyZWQgYmV0d2VlbiAqKmA2NWAqKiBhbmQgKipgNzVgKiosIHdpdGggYSBzaGFycCBwZWFrIGFyb3VuZCB0aGUgbWlkLTYwcy4gVGhlIHNtYWxsZXIgc2FtcGxlIHNpemUgaXMgcmVmbGVjdGVkIGluIHRoZSBsb3dlciBmcmVxdWVuY2llcy4NCi0gKipObyBMZWFybmluZyBEaXNhYmlsaXRpZXMqKjogVGhlIGRpc3RyaWJ1dGlvbiBpcyBicm9hZGVyLCB3aXRoIHNjb3JlcyByYW5naW5nIGZyb20gKipgNjBgKiogdG8gKipgODVgKiogYW5kIGEgcGVhayBhcm91bmQgKipgNzBgKiouDQpUaGUgbGFyZ2VyIHNhbXBsZSBzaXplIHJlc3VsdHMgaW4gaGlnaGVyIGZyZXF1ZW5jaWVzLg0KDQpTdHVkZW50cyB3aXRob3V0IGxlYXJuaW5nIGRpc2FiaWxpdGllcyBnZW5lcmFsbHkgZXhoaWJpdCBhIHNsaWdodGx5IHdpZGVyIHNwcmVhZCBvZiBleGFtIHNjb3Jlcywgd2l0aCBoaWdoZXIgbWF4aW11bSBzY29yZXMgY29tcGFyZWQgdG8gdGhvc2Ugd2l0aCBsZWFybmluZyBkaXNhYmlsaXRpZXMuIFRoZSB0aWdodGVyIGNsdXN0ZXJpbmcgZm9yIHN0dWRlbnRzIHdpdGggbGVhcm5pbmcgZGlzYWJpbGl0aWVzIG1heSBzdWdnZXN0IGNvbnNpc3RlbnQgYnV0IHNsaWdodGx5IGxvd2VyIHNjb3JlcywgcG90ZW50aWFsbHkgaGlnaGxpZ2h0aW5nIHRoZSBuZWVkIGZvciB0YXJnZXRlZCBhY2FkZW1pYyBzdXBwb3J0Lg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBsZWFybmluZyBkaXNhYmlsaXRpZXMNCnN1bW1hcnkobGVhcm5pbmdfZGlzYWJpbGl0aWVzX2V4YW1fc2NvcmUpDQpzdW1tYXJ5KG5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllc19leGFtX3Njb3JlKQ0KDQojIFdpbGNveG9uIHJhbmstc3VtIHRlc3QgZm9yIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGxlYXJuaW5nIGRpc2FiaWxpdGllcw0Kd2lsY294LnRlc3QobGVhcm5pbmdfZGlzYWJpbGl0aWVzX2V4YW1fc2NvcmUsIG5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllc19leGFtX3Njb3JlKQ0KYGBgDQoNClRoZSBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBsZWFybmluZyBkaXNhYmlsaXRpZXMsIHdpdGggYSBwLXZhbHVlIGxlc3MgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IGxlYXJuaW5nIGRpc2FiaWxpdGllcyBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBmaW5hbCBleGFtIHNjb3Jlcywgd2l0aCBzdHVkZW50cyB3aXRob3V0IGxlYXJuaW5nIGRpc2FiaWxpdGllcyBzY29yaW5nIGhpZ2hlciBvbiBhdmVyYWdlLiBUaGlzIGluZGljYXRlcyB0aGF0IHN0dWRlbnRzIHdpdGggbGVhcm5pbmcgZGlzYWJpbGl0aWVzIG1heSByZXF1aXJlIGFkZGl0aW9uYWwgc3VwcG9ydCB0byBpbXByb3ZlIHRoZWlyIGFjYWRlbWljIHBlcmZvcm1hbmNlLg0KDQojIyMgRGlzdHJpYnV0aW9uIG9mIEZpbmFsIEV4YW0gU2NvcmVzKFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgZGF0YQ0KaGlnaF9zY2hvb2xfZWR1Y2F0aW9uX2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiSGlnaCBTY2hvb2wiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkhpZ2ggU2Nob29sIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJIaWdoIFNjaG9vbCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KY29sbGVnZV9lZHVjYXRpb25fZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJDb2xsZWdlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJDb2xsZWdlIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJDb2xsZWdlIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpwb3N0Z3JhZHVhdGVfZWR1Y2F0aW9uX2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiUG9zdGdyYWR1YXRlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJQb3N0Z3JhZHVhdGUiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIlBvc3RncmFkdWF0ZSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIEhpc3RvZ3JhbSBvZiBmaW5hbCBleGFtIHNjb3JlcyBieSBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWwNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfc2Nob29sX2VkdWNhdGlvbl9leGFtX3Njb3JlLCBtYWluID0gIkhpZ2ggU2Nob29sIEVkdWNhdGlvbiIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QoY29sbGVnZV9lZHVjYXRpb25fZXhhbV9zY29yZSwgbWFpbiA9ICJDb2xsZWdlIEVkdWNhdGlvbiIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QocG9zdGdyYWR1YXRlX2VkdWNhdGlvbl9leGFtX3Njb3JlLCBtYWluID0gIlBvc3RncmFkdWF0ZSBFZHVjYXRpb24iLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KLSAqKkhpZ2ggU2Nob29sIEVkdWNhdGlvbioqOiBTY29yZXMgYXJlIHRpZ2h0bHkgY2x1c3RlcmVkLCBtb3N0bHkgYmV0d2VlbiAqKjY1YCoqIGFuZCAqKmA3NSoqYC4gVGhlIGZyZXF1ZW5jeSBpcyBoaWdoZXN0IGFtb25nIGFsbCB0aHJlZSBjYXRlZ29yaWVzLCByZWZsZWN0aW5nIGEgbGFyZ2VyIG51bWJlciBvZiBzdHVkZW50cyBmcm9tIHRoaXMgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsLg0KLSAqKkNvbGxlZ2UgRWR1Y2F0aW9uKio6IFRoZSBkaXN0cmlidXRpb24gYnJvYWRlbnMgc2xpZ2h0bHkgY29tcGFyZWQgdG8gdGhlIEhpZ2ggU2Nob29sIGdyb3VwLiBUaGUgc2NvcmVzIG1vc3RseSByYW5nZSBiZXR3ZWVuICoqYDY1YCoqIGFuZCAqKmA4MGAqKiwgd2l0aCBhIHNsaWdodCBpbmNyZWFzZSBpbiBoaWdoZXIgc2NvcmVzIChjbG9zZXIgdG8gKipgODBgKiopLiBUaGUgZnJlcXVlbmN5IGlzIG1vZGVyYXRlLg0KLSAqKlBvc3RncmFkdWF0ZSBFZHVjYXRpb24qKjogVGhlIGRpc3RyaWJ1dGlvbiBpcyB0aGUgd2lkZXN0LCB3aXRoIHNjb3JlcyByYW5naW5nIGZyb20gKipgNjBgKiogdG8gKipgODVgKiouIFRoZSBwZWFrIGZyZXF1ZW5jeSBvY2N1cnMgYXJvdW5kICoqYDcwYCoqLCBidXQgdGhlcmUgYXJlIG1vcmUgc3R1ZGVudHMgc2NvcmluZyBhYm92ZSAqKmA4MGAqKiBjb21wYXJlZCB0byB0aGUgb3RoZXIgZ3JvdXBzLg0KDQpUaGVyZSBpcyBhIGNsZWFyIHRyZW5kIG9mIGhpZ2hlciBhdmVyYWdlIHNjb3JlcyBmb3Igc3R1ZGVudHMgd2l0aCBwYXJlbnRzIHdobyBoYXZlIGhpZ2hlciBlZHVjYXRpb24gbGV2ZWxzLiBUaGUgZGlzdHJpYnV0aW9uIG9mIHNjb3JlcyB3aWRlbnMgYXMgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsIGluY3JlYXNlcywgaW5kaWNhdGluZyBhIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gcGFyZW50YWwgZWR1Y2F0aW9uIGFuZCBzdHVkZW50IHBlcmZvcm1hbmNlLiBUaGlzIHRyZW5kIHN1Z2dlc3RzIHRoYXQgc3R1ZGVudHMgd2l0aCBwYXJlbnRzIHdobyBoYXZlIGhpZ2hlciBlZHVjYXRpb24gbGV2ZWxzIG1heSBoYXZlIGJldHRlciBhY2FkZW1pYyBzdXBwb3J0IGFuZCByZXNvdXJjZXMsIGxlYWRpbmcgdG8gaW1wcm92ZWQgZXhhbSBzY29yZXMuDQoNCmBgYHtyfQ0KIyBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzaGFwaXJvLnRlc3QoaGlnaF9zY2hvb2xfZWR1Y2F0aW9uX2V4YW1fc2NvcmUpDQpzaGFwaXJvLnRlc3QoY29sbGVnZV9lZHVjYXRpb25fZXhhbV9zY29yZSkNCnNoYXBpcm8udGVzdChwb3N0Z3JhZHVhdGVfZWR1Y2F0aW9uX2V4YW1fc2NvcmUpDQpgYGANCg0KVGhlIFNoYXBpcm8tV2lsayB0ZXN0IGNvbmZpcm1zIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3IgYWxsIHN0dWRlbnRzIGlzIG5vdCBub3JtYWwsIHdpdGggYSBwLXZhbHVlIGxlc3MgdGhhbiAwLjA1Lg0KDQpXZSBub3cgdXNlIEtydXNrYWwtV2FsbGlzIHRlc3QgdG8gY2hlY2sgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGlzIGRpZmZlcmVudCBiYXNlZCBvbiBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWwNCnN1bW1hcnkoaGlnaF9zY2hvb2xfZWR1Y2F0aW9uX2V4YW1fc2NvcmUpDQpzdW1tYXJ5KGNvbGxlZ2VfZWR1Y2F0aW9uX2V4YW1fc2NvcmUpDQpzdW1tYXJ5KHBvc3RncmFkdWF0ZV9lZHVjYXRpb25fZXhhbV9zY29yZSkNCg0KIyBLcnVza2FsLVdhbGxpcyB0ZXN0IGZvciBmaW5hbCBleGFtIHNjb3JlcyBieSBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWwNCmtydXNrYWwudGVzdChFeGFtX1Njb3JlIH4gUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzIGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIGZpbmFsIGV4YW0gc2NvcmVzLiBGcm9tIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MsIHdlIGNhbiBzZWUgdGhhdCBzdHVkZW50cyB3aXRoIHBhcmVudHMgd2hvIGhhdmUgcG9zdGdyYWR1YXRlIGVkdWNhdGlvbiBoYXZlIGhpZ2hlciBhdmVyYWdlIGV4YW0gc2NvcmVzLCBmb2xsb3dlZCBieSBzdHVkZW50cyB3aXRoIHBhcmVudHMgd2hvIGhhdmUgY29sbGVnZSBlZHVjYXRpb24sIGFuZCBzdHVkZW50cyB3aXRoIHBhcmVudHMgd2hvIGhhdmUgaGlnaCBzY2hvb2wgZWR1Y2F0aW9uIGhhdmUgdGhlIGxvd2VzdCBhdmVyYWdlIGV4YW0gc2NvcmVzLiBUaGlzIHRyZW5kIHN1Z2dlc3RzIHRoYXQgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsIGlzIGEgc3Ryb25nIHByZWRpY3RvciBvZiBzdHVkZW50IHBlcmZvcm1hbmNlLg0KDQojIyMgRGlzdHJpYnV0aW9uIG9mIEZpbmFsIEV4YW0gU2NvcmVzIChEaXN0YW5jZV9mcm9tX0hvbWUgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbC4NCg0KYGBge3J9DQojIFNhbXBsZSBkYXRhDQpuZWFyX2Rpc3RhbmNlX2V4YW1fc2NvcmUgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiTmVhciJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiTmVhciIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiTmVhciIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbW9kZXJhdGVfZGlzdGFuY2VfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJNb2RlcmF0ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiTW9kZXJhdGUiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIk1vZGVyYXRlIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpmYXJfZGlzdGFuY2VfZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJGYXIiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIkZhciIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiRmFyIikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGRpc3RhbmNlIGZyb20gaG9tZQ0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QobmVhcl9kaXN0YW5jZV9leGFtX3Njb3JlLCBtYWluID0gIk5lYXIgRGlzdGFuY2UiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1vZGVyYXRlX2Rpc3RhbmNlX2V4YW1fc2NvcmUsIG1haW4gPSAiTW9kZXJhdGUgRGlzdGFuY2UiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGZhcl9kaXN0YW5jZV9leGFtX3Njb3JlLCBtYWluID0gIkZhciBEaXN0YW5jZSIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQpUaGUgZGlzdHJpYnV0aW9ucyBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBkaXN0YW5jZSBmcm9tIGhvbWUgdG8gc2Nob29sIHNob3cgYSBzaW1pbGFyIHBhdHRlcm4gYWNyb3NzIGFsbCBjYXRlZ29yaWVzLiBUaGUgc2NvcmVzIGFyZSBjbHVzdGVyZWQgYmV0d2VlbiAqKmA2MGAqKiBhbmQgKipgNzVgKiogZm9yIGFsbCBkaXN0YW5jZSBsZXZlbHMsIHdpdGggYSBmZXcgb3V0bGllcnMgc2NvcmluZyBhYm92ZSA4MC4gVGhlIGRpc3RyaWJ1dGlvbiBpcyBzbGlnaHRseSB3aWRlciBmb3Igc3R1ZGVudHMgbGl2aW5nIGZhciBmcm9tIHNjaG9vbCwgaW5kaWNhdGluZyBhIHNsaWdodGx5IGhpZ2hlciB2YXJpYWJpbGl0eSBpbiBzY29yZXMgY29tcGFyZWQgdG8gc3R1ZGVudHMgbGl2aW5nIG5lYXIgb3IgYXQgYSBtb2RlcmF0ZSBkaXN0YW5jZSBmcm9tIHNjaG9vbC4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgZGlzdGFuY2UgZnJvbSBob21lDQpzdW1tYXJ5KG5lYXJfZGlzdGFuY2VfZXhhbV9zY29yZSkNCnN1bW1hcnkobW9kZXJhdGVfZGlzdGFuY2VfZXhhbV9zY29yZSkNCnN1bW1hcnkoZmFyX2Rpc3RhbmNlX2V4YW1fc2NvcmUpDQoNCiMgS3J1c2thbC1XYWxsaXMgdGVzdCBmb3IgZmluYWwgZXhhbSBzY29yZXMgYnkgZGlzdGFuY2UgZnJvbSBob21lDQprcnVza2FsLnRlc3QoRXhhbV9TY29yZSB+IERpc3RhbmNlX2Zyb21fSG9tZSwgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgZGlzdGFuY2UgZnJvbSBob21lIGhhcyBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgZmluYWwgZXhhbSBzY29yZXMuIEZyb20gdGhlIHN1bW1hcnkgc3RhdGlzdGljcywgd2UgY2FuIHNlZSB0aGF0IHN0dWRlbnRzIGxpdmluZyBuZWFyIHRvIHNjaG9vbCBoYXZlIGhpZ2hlciBhdmVyYWdlIGV4YW0gc2NvcmVzLCBmb2xsb3dlZCBieSBzdHVkZW50cyBsaXZpbmcgYXQgYSBtb2RlcmF0ZSBkaXN0YW5jZSwgYW5kIHN0dWRlbnRzIGxpdmluZyBmYXIgZnJvbSBzY2hvb2wgaGF2ZSB0aGUgbG93ZXN0IGF2ZXJhZ2UgZXhhbSBzY29yZXMuIFRoaXMgdHJlbmQgc3VnZ2VzdHMgdGhhdCBzdHVkZW50cyBsaXZpbmcgZmFyIGZyb20gc2Nob29sIG1heSBoYXZlIGJldHRlciBhY2FkZW1pYyBzdXBwb3J0IG9yIHJlc291cmNlcywgbGVhZGluZyB0byBpbXByb3ZlZCBleGFtIHNjb3Jlcy4NCg0KIyMjIFN1bW1hcnkgb2YgRGlzdHJpYnV0aW9uIEFuYWx5c2lzDQoNCkluIHN1bW1hcnksIHRoZSBkaXN0cmlidXRpb24gYW5hbHlzaXMgb2YgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gdmFyaW91cyBmYWN0b3JzIHJldmVhbHMgdGhlIGZvbGxvd2luZyBpbnNpZ2h0czoNCg0KLSAqKlBhcmVudGFsIEludm9sdmVtZW50Kio6IFRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMsIHdpdGggc3R1ZGVudHMgaGF2aW5nIGhpZ2ggcGFyZW50YWwgaW52b2x2ZW1lbnQgc2NvcmluZyBoaWdoZXIgb24gYXZlcmFnZS4NCi0gKipBY2Nlc3MgdG8gUmVzb3VyY2VzKio6IFRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLCB3aXRoIHN0dWRlbnRzIGhhdmluZyBoaWdoIGFjY2VzcyB0byByZXNvdXJjZXMgc2NvcmluZyBoaWdoZXIgb24gYXZlcmFnZS4NCi0gKipFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyoqOiBQYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gZmluYWwgZXhhbSBzY29yZXMuDQotICoqTW90aXZhdGlvbiBMZXZlbCoqOiBUaGVyZSBpcyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gbW90aXZhdGlvbiBsZXZlbHMsIHdpdGggc3R1ZGVudHMgaGF2aW5nIGhpZ2ggbW90aXZhdGlvbiBzY29yaW5nIGhpZ2hlciBvbiBhdmVyYWdlLg0KLSAqKkludGVybmV0IEFjY2VzcyoqOiBJbnRlcm5ldCBhY2Nlc3MgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBmaW5hbCBleGFtIHNjb3Jlcy4NCi0gKipGYW1pbHkgSW5jb21lKio6IFRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscywgd2l0aCBzdHVkZW50cyBmcm9tIGhpZ2gtaW5jb21lIGZhbWlsaWVzIHNjb3JpbmcgaGlnaGVyIG9uIGF2ZXJhZ2UuDQotICoqVGVhY2hlciBRdWFsaXR5Kio6IFRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLCB3aXRoIHN0dWRlbnRzIGhhdmluZyBoaWdoIHRlYWNoZXIgcXVhbGl0eSBzY29yaW5nIGhpZ2hlciBvbiBhdmVyYWdlLg0KLSAqKlNjaG9vbCBUeXBlKio6IFNjaG9vbCB0eXBlIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gZmluYWwgZXhhbSBzY29yZXMuDQotICoqUGVlciBJbmZsdWVuY2UqKjogVGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscywgd2l0aCBzdHVkZW50cyBoYXZpbmcgcG9zaXRpdmUgcGVlciBpbmZsdWVuY2Ugc2NvcmluZyBoaWdoZXIgb24gYXZlcmFnZS4NCi0gKipMZWFybmluZyBEaXNhYmlsaXRpZXMqKjogVGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIGxlYXJuaW5nIGRpc2FiaWxpdGllcywgd2l0aCBzdHVkZW50cyB3aXRob3V0IGxlYXJuaW5nIGRpc2FiaWxpdGllcyBzY29yaW5nIGhpZ2hlciBvbiBhdmVyYWdlLg0KLSAqKlBhcmVudGFsIEVkdWNhdGlvbiBMZXZlbCoqOiBUaGVyZSBpcyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscywgd2l0aCBzdHVkZW50cyBoYXZpbmcgcGFyZW50cyB3aXRoIHBvc3RncmFkdWF0ZSBlZHVjYXRpb24gc2NvcmluZyBoaWdoZXIgb24gYXZlcmFnZS4NCi0gKipEaXN0YW5jZSBmcm9tIEhvbWUqKjogVGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIGRpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wsIHdpdGggc3R1ZGVudHMgbGl2aW5nIG5lYXIgdG8gc2Nob29sIHNjb3JpbmcgaGlnaGVyIG9uIGF2ZXJhZ2UNCg0KIyBBdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlaw0KDQojIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKFdpdGhvdXQgQ29uc2lkZXJpbmcgT3RoZXIgRmFjdG9ycykNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgd2l0aG91dCBjb25zaWRlcmluZyBvdGhlciBmYWN0b3JzLg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0Kc2FtcGxlX2hvdXJzX3N0dWRpZWQgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc2FtcGxlKG5yb3coc3R1ZGVudF9kYXRhKSwgcm91bmQobnJvdyhzdHVkZW50X2RhdGEpKnNhbXBsZV9mcmFjdGlvbikpXQ0Kc3VtbWFyeShzYW1wbGVfaG91cnNfc3R1ZGllZCkNCmBgYA0KDQpXZSB3aWxsIG5vdyB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyB1c2luZyBhIGhpc3RvZ3JhbS4NCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMNCmhpc3Qoc2FtcGxlX2hvdXJzX3N0dWRpZWQsIG1haW4gPSAiRGlzdHJpYnV0aW9uIG9mIFN0dWR5IEhvdXJzIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQpUaGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGFwcGVhcnMgdG8gYmUgbm9ybWFsLiBXZSB3aWxsIG5vdyB1c2UgbnVtZXJpY2FsIG1ldGhvZHMgdG8gY29uZmlybSB0aGUgbm9ybWFsaXR5IG9mIHRoZSBkaXN0cmlidXRpb24uDQoNCmBgYHtyfQ0KIyBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzaGFwaXJvLnRlc3Qoc2FtcGxlX2hvdXJzX3N0dWRpZWQpDQpgYGANCg0KVGhlIHAtdmFsdWUgaXMgbGVzcyB0aGFuIDAuMDUsIGluZGljYXRpbmcgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIG5vdCBub3JtYWwuDQoNCiMjIyBBdmVyYWdlIE51bWJlciBvZiBIb3VycyBTdHVkZW50cyBTdHVkeSBwZXIgV2VlayAoUGFyZW50YWxfSW52b2x2ZW1lbnQgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIHdpbGwgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudF9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkhpZ2giKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiSGlnaCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50X2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJNZWRpdW0iKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTWVkaXVtIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnRfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkxvdyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJMb3ciKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IHBhcmVudGFsIGludm9sdmVtZW50DQpzdW1tYXJ5KGhpZ2hfcGFyZW50YWxfaW52b2x2ZW1lbnRfaHJzKQ0Kc3VtbWFyeShtZWRpdW1fcGFyZW50YWxfaW52b2x2ZW1lbnRfaHJzKQ0Kc3VtbWFyeShsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnRfaHJzKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBkbyBub3Qgc2hvdyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgcGFyZW50YWwgaW52b2x2ZW1lbnQNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfcGFyZW50YWxfaW52b2x2ZW1lbnRfaHJzLCBtYWluID0gIkhpZ2ggUGFyZW50YWwgSW52b2x2ZW1lbnQiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1fcGFyZW50YWxfaW52b2x2ZW1lbnRfaHJzLCBtYWluID0gIk1lZGl1bSBQYXJlbnRhbCBJbnZvbHZlbWVudCIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGxvd19wYXJlbnRhbF9pbnZvbHZlbWVudF9ocnMsIG1haW4gPSAiTG93IFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QoaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudF9ocnMpDQpzaGFwaXJvLnRlc3QobWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50X2hycykNCnNoYXBpcm8udGVzdChsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnRfaHJzKQ0KYGBgDQoNClNoYXBpcm8tV2lsayB0ZXN0IHNob3dzIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBmb3Igc3R1ZGVudHMgd2l0aCBoaWdoIGFuZCBsb3cgcGFyZW50YWwgaW52b2x2ZW1lbnQsIGJ1dCBub3QgZm9yIHN0dWRlbnRzIHdpdGggbWVkaXVtIHBhcmVudGFsIGludm9sdmVtZW50LiBXZSB3aWxsIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscy4NCg0KYGBge3J9DQojIEtydXNrYWwtV2FsbGlzIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHBhcmVudGFsIGludm9sdmVtZW50DQprcnVza2FsLnRlc3QoSG91cnNfU3R1ZGllZCB+IFBhcmVudGFsX0ludm9sdmVtZW50LCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBwYXJlbnRhbCBpbnZvbHZlbWVudCBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgc3R1ZHkgaG91cnMgYXJlIGluZGVwZW5kZW50IG9mIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscy4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgcGFyZW50YWwgaW52b2x2ZW1lbnQNCnRhYmxlX3BhcmVudGFsX2ludm9sdmVtZW50X2hvdXJzIDwtIHRhYmxlKHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkLCBzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQpDQpjaGlzcS50ZXN0KHRhYmxlX3BhcmVudGFsX2ludm9sdmVtZW50X2hvdXJzKQ0KYGBgDQoNClRoZSBDaGktc3F1YXJlIHRlc3Qgc2hvd3MgdGhhdCBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2YgcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBmdXJ0aGVyIGNvbmZpcm1zIHRoYXQgcGFyZW50YWwgaW52b2x2ZW1lbnQgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKEFjY2Vzc190b19SZXNvdXJjZXMgQ2F0ZWdvcnkpDQoNCldlIG5vdyBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpoaWdoX2FjY2Vzc190b19yZXNvdXJjZXNfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiSGlnaCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkhpZ2giKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTWVkaXVtIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTWVkaXVtIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpsb3dfYWNjZXNzX3RvX3Jlc291cmNlc19ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc3R1ZHkgaG91cnMgYnkgYWNjZXNzIHRvIHJlc291cmNlcw0Kc3VtbWFyeShoaWdoX2FjY2Vzc190b19yZXNvdXJjZXNfaHJzKQ0Kc3VtbWFyeShtZWRpdW1fYWNjZXNzX3RvX3Jlc291cmNlc19ocnMpDQpzdW1tYXJ5KGxvd19hY2Nlc3NfdG9fcmVzb3VyY2VzX2hycykNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzIGRvIG5vdCBzaG93IHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBhY2Nlc3MgdG8gcmVzb3VyY2VzDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX2FjY2Vzc190b19yZXNvdXJjZXNfaHJzLCBtYWluID0gIkhpZ2ggQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2hycywgbWFpbiA9ICJNZWRpdW0gQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGxvd19hY2Nlc3NfdG9fcmVzb3VyY2VzX2hycywgbWFpbiA9ICJMb3cgQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChoaWdoX2FjY2Vzc190b19yZXNvdXJjZXNfaHJzKQ0Kc2hhcGlyby50ZXN0KG1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2hycykNCnNoYXBpcm8udGVzdChsb3dfYWNjZXNzX3RvX3Jlc291cmNlc19ocnMpDQpgYGANCg0KU2hhcGlyby1XaWxrIHRlc3Qgc2hvd3MgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBzdHVkZW50cyB3aXRoIGhpZ2ggYW5kIGxvdyBhY2Nlc3MgdG8gcmVzb3VyY2VzLCBidXQgbm90IGZvciBzdHVkZW50cyB3aXRoIG1lZGl1bSBhY2Nlc3MgdG8gcmVzb3VyY2VzLiBXZSB3aWxsIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIGFjY2VzcyB0byByZXNvdXJjZXMgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgS3J1c2thbC1XYWxsaXMgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgYWNjZXNzIHRvIHJlc291cmNlcw0Ka3J1c2thbC50ZXN0KEhvdXJzX1N0dWRpZWQgfiBBY2Nlc3NfdG9fUmVzb3VyY2VzLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcyBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IGFjY2VzcyB0byByZXNvdXJjZXMgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQpOb3cgd2UgdXNlIENoaS1zcXVhcmUgdGVzdCB0byBjaGVjayB3aGV0aGVyIHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiBhY2Nlc3MgdG8gcmVzb3VyY2VzIGxldmVscy4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgYWNjZXNzIHRvIHJlc291cmNlcw0KdGFibGVfYWNjZXNzX3RvX3Jlc291cmNlc19ob3VycyA8LSB0YWJsZShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZCwgc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMpDQpjaGlzcS50ZXN0KHRhYmxlX2FjY2Vzc190b19yZXNvdXJjZXNfaG91cnMpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiBhY2Nlc3MgdG8gcmVzb3VyY2VzIGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgZnVydGhlciBjb25maXJtcyB0aGF0IGFjY2VzcyB0byByZXNvdXJjZXMgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJZZXMiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiWWVzIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBzdHVkeSBob3VycyBieSBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcw0Kc3VtbWFyeShwYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfaHJzKQ0Kc3VtbWFyeShkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2hycykNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiB0LXRlc3QuDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpoaXN0KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9ocnMsIG1haW4gPSAiRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2hycywgbWFpbiA9ICJObyBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgdC10ZXN0DQpzaGFwaXJvLnRlc3QocGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2hycykNCnNoYXBpcm8udGVzdChkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2hycykNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvd3MgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIG5vdCBub3JtYWwgZm9yIGFsbCBzdHVkZW50cy4gV2Ugd2lsbCBub3cgdXNlIFdpbGNveG9uIHJhbmstc3VtIHRlc3QgdG8gY2hlY2sgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGRpZmZlcmVudCBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLg0KDQpgYGB7cn0NCiMgV2lsY294b24gcmFuay1zdW0gdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMNCndpbGNveC50ZXN0KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9ocnMsIGRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfaHJzKQ0KYGBgDQoNClRoZSBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcyBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgc3R1ZHkgaG91cnMgYXJlIGluZGVwZW5kZW50IG9mIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQp0YWJsZV9leHRyYWN1cnJpY3VsYXJfYWN0aXZpdGllc19ob3VycyA8LSB0YWJsZShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZCwgc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzKQ0KY2hpc3EudGVzdCh0YWJsZV9leHRyYWN1cnJpY3VsYXJfYWN0aXZpdGllc19ob3VycykNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgc3R1ZHkgaG91cnMgYXJlIGluZGVwZW5kZW50IG9mIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChNb3RpdmF0aW9uX0xldmVsIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBtb3RpdmF0aW9uIGxldmVscy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaGlnaF9tb3RpdmF0aW9uX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiSGlnaCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkhpZ2giKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJIaWdoIikqc2FtcGxlX2ZyYWN0aW9uKSldDQptZWRpdW1fbW90aXZhdGlvbl9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIk1lZGl1bSIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIk1lZGl1bSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbG93X21vdGl2YXRpb25faHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJMb3ciKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IG1vdGl2YXRpb24gbGV2ZWwNCnN1bW1hcnkoaGlnaF9tb3RpdmF0aW9uX2hycykNCnN1bW1hcnkobWVkaXVtX21vdGl2YXRpb25faHJzKQ0Kc3VtbWFyeShsb3dfbW90aXZhdGlvbl9ocnMpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gbW90aXZhdGlvbiBsZXZlbHMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIG1vdGl2YXRpb24gbGV2ZWxzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIEFOT1ZBLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIHN0dWR5IGhvdXJzIGJ5IG1vdGl2YXRpb24gbGV2ZWwNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfbW90aXZhdGlvbl9ocnMsIG1haW4gPSAiSGlnaCBNb3RpdmF0aW9uIExldmVsIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX21vdGl2YXRpb25faHJzLCBtYWluID0gIk1lZGl1bSBNb3RpdmF0aW9uIExldmVsIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobG93X21vdGl2YXRpb25faHJzLCBtYWluID0gIkxvdyBNb3RpdmF0aW9uIExldmVsIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBDaGVjayBhc3N1bXB0aW9ucyBvZiBBTk9WQQ0Kc2hhcGlyby50ZXN0KGhpZ2hfbW90aXZhdGlvbl9ocnMpDQpzaGFwaXJvLnRlc3QobWVkaXVtX21vdGl2YXRpb25faHJzKQ0Kc2hhcGlyby50ZXN0KGxvd19tb3RpdmF0aW9uX2hycykNCmBgYA0KDQpTaGFwaXJvLVdpbGsgdGVzdCBzaG93cyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgb2Ygc3R1ZGVudHMgd2l0aCBoaWdoIGFuZCBtZWRpdW0gbW90aXZhdGlvbiBpcyBub3Qgbm9ybWFsLCB3aXRoIGEgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNS4gV2Ugd2lsbCBub3cgdXNlIEtydWtzYWwtV2FsbGlzIHRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gbW90aXZhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBLcnVza2FsLVdhbGxpcyB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBtb3RpdmF0aW9uIGxldmVsDQprcnVza2FsLnRlc3QoSG91cnNfU3R1ZGllZCB+IE1vdGl2YXRpb25fTGV2ZWwsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydXNrYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBtb3RpdmF0aW9uIGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgbW90aXZhdGlvbiBsZXZlbHMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2YgbW90aXZhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IG1vdGl2YXRpb24gbGV2ZWwNCnRhYmxlX21vdGl2YXRpb25fbGV2ZWxfaG91cnMgPC0gdGFibGUoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWQsIHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsKQ0KY2hpc3EudGVzdCh0YWJsZV9tb3RpdmF0aW9uX2xldmVsX2hvdXJzKQ0KYGBgDQoNClRoZSBDaGktc3F1YXJlIHRlc3Qgc2hvd3MgdGhhdCBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2YgbW90aXZhdGlvbiBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBtb3RpdmF0aW9uIGxldmVscyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKEludGVybmV0IEFjY2VzcyBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQppbnRlcm5ldF9hY2Nlc3NfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiWWVzIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkSW50ZXJuZXRfQWNjZXNzID09ICJZZXMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm5vX2ludGVybmV0X2FjY2Vzc19ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiTm8iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIk5vIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkSW50ZXJuZXRfQWNjZXNzID09ICJObyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc3R1ZHkgaG91cnMgYnkgaW50ZXJuZXQgYWNjZXNzDQpzdW1tYXJ5KGludGVybmV0X2FjY2Vzc19ocnMpDQpzdW1tYXJ5KG5vX2ludGVybmV0X2FjY2Vzc19ocnMpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIHQtdGVzdC4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBpbnRlcm5ldCBhY2Nlc3MNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpoaXN0KGludGVybmV0X2FjY2Vzc19ocnMsIG1haW4gPSAiSW50ZXJuZXQgQWNjZXNzIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3Qobm9faW50ZXJuZXRfYWNjZXNzX2hycywgbWFpbiA9ICJObyBJbnRlcm5ldCBBY2Nlc3MiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIHQtdGVzdA0Kc2hhcGlyby50ZXN0KGludGVybmV0X2FjY2Vzc19ocnMpDQpzaGFwaXJvLnRlc3Qobm9faW50ZXJuZXRfYWNjZXNzX2hycykNCmBgYA0KDQpTaGFwaXJvLVdpbGsgdGVzdCBzaG93cyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgYXBwcm94aW1hdGVseSBub3JtYWwgZm9yIHN0dWRlbnRzIHdpdGggbm8gaW50ZXJuZXQgYWNjZXNzLCBidXQgbm90IGZvciBzdHVkZW50cyB3aXRoIGludGVybmV0IGFjY2Vzcy4gV2Ugd2lsbCBub3cgdXNlIFdpbGNveG9uIHJhbmstc3VtIHRlc3QgdG8gY2hlY2sgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGRpZmZlcmVudCBiYXNlZCBvbiBpbnRlcm5ldCBhY2Nlc3MuDQoNCmBgYHtyfQ0KIyBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBpbnRlcm5ldCBhY2Nlc3MNCndpbGNveC50ZXN0KGludGVybmV0X2FjY2Vzc19ocnMsIG5vX2ludGVybmV0X2FjY2Vzc19ocnMpDQpgYGANCg0KVGhlIHAtdmFsdWUgaXMgbGVzcyB0aGFuIDAuMDUsIGluZGljYXRpbmcgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIGludGVybmV0IGFjY2Vzcy4gVGhpcyBzdWdnZXN0cyB0aGF0IGludGVybmV0IGFjY2VzcyBoYXMgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2YgaW50ZXJuZXQgYWNjZXNzLg0KDQpgYGB7cn0NCiMgQ2hpLXNxdWFyZSB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBpbnRlcm5ldCBhY2Nlc3MNCnRhYmxlX2ludGVybmV0X2FjY2Vzc19ob3VycyA8LSB0YWJsZShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZCwgc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcykNCmNoaXNxLnRlc3QodGFibGVfaW50ZXJuZXRfYWNjZXNzX2hvdXJzKQ0KYGBgDQoNClRoZSBDaGktc3F1YXJlIHRlc3Qgc2hvd3MgdGhhdCBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2YgaW50ZXJuZXQgYWNjZXNzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4NCg0KIyMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChGYW1pbHkgSW5jb21lIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KbG93X2ZhbWlseV9pbmNvbWVfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm1lZGl1bV9mYW1pbHlfaW5jb21lX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTWVkaXVtIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTWVkaXVtIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpoaWdoX2ZhbWlseV9pbmNvbWVfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiSGlnaCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIkhpZ2giKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IGZhbWlseSBpbmNvbWUNCnN1bW1hcnkobG93X2ZhbWlseV9pbmNvbWVfaHJzKQ0Kc3VtbWFyeShtZWRpdW1fZmFtaWx5X2luY29tZV9ocnMpDQpzdW1tYXJ5KGhpZ2hfZmFtaWx5X2luY29tZV9ocnMpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gZmFtaWx5IGluY29tZSBsZXZlbHMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIGZhbWlseSBpbmNvbWUgbGV2ZWxzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIEFOT1ZBLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIHN0dWR5IGhvdXJzIGJ5IGZhbWlseSBpbmNvbWUNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGxvd19mYW1pbHlfaW5jb21lX2hycywgbWFpbiA9ICJMb3cgRmFtaWx5IEluY29tZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV9mYW1pbHlfaW5jb21lX2hycywgbWFpbiA9ICJNZWRpdW0gRmFtaWx5IEluY29tZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGhpZ2hfZmFtaWx5X2luY29tZV9ocnMsIG1haW4gPSAiSGlnaCBGYW1pbHkgSW5jb21lIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBDaGVjayBhc3N1bXB0aW9ucyBvZiBBTk9WQQ0Kc2hhcGlyby50ZXN0KGxvd19mYW1pbHlfaW5jb21lX2hycykNCnNoYXBpcm8udGVzdChtZWRpdW1fZmFtaWx5X2luY29tZV9ocnMpDQpzaGFwaXJvLnRlc3QoaGlnaF9mYW1pbHlfaW5jb21lX2hycykNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvd3MgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBzdHVkZW50cyB3aXRoIGxvdyBhbmQgaGlnaCBmYW1pbHkgaW5jb21lLCBidXQgbm90IGZvciBzdHVkZW50cyB3aXRoIG1lZGl1bSBmYW1pbHkgaW5jb21lLiBXZSB3aWxsIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byBjaGVjayB3aGV0aGVyIHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgZGlmZmVyZW50IGJhc2VkIG9uIGZhbWlseSBpbmNvbWUgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgS3J1c2thbC1XYWxsaXMgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgZmFtaWx5IGluY29tZQ0Ka3J1c2thbC50ZXN0KEhvdXJzX1N0dWRpZWQgfiBGYW1pbHlfSW5jb21lLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gZmFtaWx5IGluY29tZSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IGZhbWlseSBpbmNvbWUgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQpOb3cgd2UgdXNlIENoaS1zcXVhcmUgdGVzdCB0byBjaGVjayB3aGV0aGVyIHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiBmYW1pbHkgaW5jb21lIGxldmVscy4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgZmFtaWx5IGluY29tZQ0KdGFibGVfZmFtaWx5X2luY29tZV9ob3VycyA8LSB0YWJsZShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZCwgc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUpDQpjaGlzcS50ZXN0KHRhYmxlX2ZhbWlseV9pbmNvbWVfaG91cnMpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiBmYW1pbHkgaW5jb21lIGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgZnVydGhlciBjb25maXJtcyB0aGF0IGZhbWlseSBpbmNvbWUgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKFRlYWNoZXIgUXVhbGl0eSBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gdGVhY2hlciBxdWFsaXR5IGxldmVscy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KbG93X3RlYWNoZXJfcXVhbGl0eV9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkxvdyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJNZWRpdW0iKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIk1lZGl1bSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KaGlnaF90ZWFjaGVyX3F1YWxpdHlfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkhpZ2giKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkhpZ2giKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IHRlYWNoZXIgcXVhbGl0eQ0Kc3VtbWFyeShsb3dfdGVhY2hlcl9xdWFsaXR5X2hycykNCnN1bW1hcnkobWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9ocnMpDQpzdW1tYXJ5KGhpZ2hfdGVhY2hlcl9xdWFsaXR5X2hycykNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSBBTk9WQSB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIEFOT1ZBLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIHN0dWR5IGhvdXJzIGJ5IHRlYWNoZXIgcXVhbGl0eQ0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QobG93X3RlYWNoZXJfcXVhbGl0eV9ocnMsIG1haW4gPSAiTG93IFRlYWNoZXIgUXVhbGl0eSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV90ZWFjaGVyX3F1YWxpdHlfaHJzLCBtYWluID0gIk1lZGl1bSBUZWFjaGVyIFF1YWxpdHkiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChoaWdoX3RlYWNoZXJfcXVhbGl0eV9ocnMsIG1haW4gPSAiSGlnaCBUZWFjaGVyIFF1YWxpdHkiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QobG93X3RlYWNoZXJfcXVhbGl0eV9ocnMpDQpzaGFwaXJvLnRlc3QobWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9ocnMpDQpzaGFwaXJvLnRlc3QoaGlnaF90ZWFjaGVyX3F1YWxpdHlfaHJzKQ0KYGBgDQoNClRoZSBTaGFwaXJvLVdpbGsgdGVzdCBzaG93cyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgYXBwcm94aW1hdGVseSBub3JtYWwgZm9yIHN0dWRlbnRzIHdpdGggbG93IGFuZCBoaWdoIHRlYWNoZXIgcXVhbGl0eSwgYnV0IG5vdCBmb3Igc3R1ZGVudHMgd2l0aCBtZWRpdW0gdGVhY2hlciBxdWFsaXR5LiBXZSB3aWxsIG5vdyB1c2UgS3J1a3NhbC1XYWxsaXMgdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgS3J1c2thbC1XYWxsaXMgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgdGVhY2hlciBxdWFsaXR5DQprcnVza2FsLnRlc3QoSG91cnNfU3R1ZGllZCB+IFRlYWNoZXJfUXVhbGl0eSwgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHRlYWNoZXIgcXVhbGl0eSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHRlYWNoZXIgcXVhbGl0eSBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgc3R1ZHkgaG91cnMgYXJlIGluZGVwZW5kZW50IG9mIHRlYWNoZXIgcXVhbGl0eSBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHRlYWNoZXIgcXVhbGl0eQ0KdGFibGVfdGVhY2hlcl9xdWFsaXR5X2hvdXJzIDwtIHRhYmxlKHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkLCBzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5KQ0KY2hpc3EudGVzdCh0YWJsZV90ZWFjaGVyX3F1YWxpdHlfaG91cnMpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBmdXJ0aGVyIGNvbmZpcm1zIHRoYXQgdGVhY2hlciBxdWFsaXR5IGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChTY2hvb2wgVHlwZSBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gYSBzY2hvb2wgdHlwZS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KcHVibGljX3NjaG9vbF9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQdWJsaWMiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRTY2hvb2xfVHlwZSA9PSAiUHVibGljIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlB1YmxpYyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KcHJpdmF0ZV9zY2hvb2xfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRTY2hvb2xfVHlwZSA9PSAiUHJpdmF0ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQcml2YXRlIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlByaXZhdGUiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IHNjaG9vbCB0eXBlDQpzdW1tYXJ5KHB1YmxpY19zY2hvb2xfaHJzKQ0Kc3VtbWFyeShwcml2YXRlX3NjaG9vbF9ocnMpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gc2Nob29sIHR5cGUgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIHQtdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiBzY2hvb2wgdHlwZS4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiB0LXRlc3QuDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgc2Nob29sIHR5cGUNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpoaXN0KHB1YmxpY19zY2hvb2xfaHJzLCBtYWluID0gIlB1YmxpYyBTY2hvb2wiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChwcml2YXRlX3NjaG9vbF9ocnMsIG1haW4gPSAiUHJpdmF0ZSBTY2hvb2wiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIHQtdGVzdA0Kc2hhcGlyby50ZXN0KHB1YmxpY19zY2hvb2xfaHJzKQ0Kc2hhcGlyby50ZXN0KHByaXZhdGVfc2Nob29sX2hycykNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvd3MgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBzdHVkZW50cyBmcm9tIHByaXZhdGUgc2Nob29scy4gV2Ugd2lsbCBub3cgdXNlIFdpbGNveG9uIHJhbmstc3VtIHRlc3QgdG8gY2hlY2sgd2hldGhlciB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGRpZmZlcmVudCBiYXNlZCBvbiBzY2hvb2wgdHlwZS4NCg0KYGBge3J9DQojIFdpbGNveG9uIHJhbmstc3VtIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHNjaG9vbCB0eXBlDQp3aWxjb3gudGVzdChwdWJsaWNfc2Nob29sX2hycywgcHJpdmF0ZV9zY2hvb2xfaHJzKQ0KYGBgDQoNClRoZSBXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gc2Nob29sIHR5cGUsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHNjaG9vbCB0eXBlIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2Ygc2Nob29sIHR5cGUuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHNjaG9vbCB0eXBlDQp0YWJsZV9zY2hvb2xfdHlwZV9ob3VycyA8LSB0YWJsZShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZCwgc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlKQ0KY2hpc3EudGVzdCh0YWJsZV9zY2hvb2xfdHlwZV9ob3VycykNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgc3R1ZHkgaG91cnMgYXJlIGluZGVwZW5kZW50IG9mIHNjaG9vbCB0eXBlLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBmdXJ0aGVyIGNvbmZpcm1zIHRoYXQgc2Nob29sIHR5cGUgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKFBlZXIgSW5mbHVlbmNlIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCnBvc2l0aXZlX3BlZXJfaW5mbHVlbmNlX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZV9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZWdhdGl2ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZWdhdGl2ZSIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZWdhdGl2ZSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbmV1dHJhbF9wZWVyX2luZmx1ZW5jZV9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZXV0cmFsIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIk5ldXRyYWwiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmV1dHJhbCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc3R1ZHkgaG91cnMgYnkgcGVlciBpbmZsdWVuY2UNCnN1bW1hcnkocG9zaXRpdmVfcGVlcl9pbmZsdWVuY2VfaHJzKQ0Kc3VtbWFyeShuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZV9ocnMpDQpzdW1tYXJ5KG5ldXRyYWxfcGVlcl9pbmZsdWVuY2VfaHJzKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGVlciBpbmZsdWVuY2UgbGV2ZWxzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIEFOT1ZBLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIHN0dWR5IGhvdXJzIGJ5IHBlZXIgaW5mbHVlbmNlDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChwb3NpdGl2ZV9wZWVyX2luZmx1ZW5jZV9ocnMsIG1haW4gPSAiUG9zaXRpdmUgUGVlciBJbmZsdWVuY2UiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZV9ocnMsIG1haW4gPSAiTmVnYXRpdmUgUGVlciBJbmZsdWVuY2UiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChuZXV0cmFsX3BlZXJfaW5mbHVlbmNlX2hycywgbWFpbiA9ICJOZXV0cmFsIFBlZXIgSW5mbHVlbmNlIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBDaGVjayBhc3N1bXB0aW9ucyBvZiBBTk9WQQ0Kc2hhcGlyby50ZXN0KHBvc2l0aXZlX3BlZXJfaW5mbHVlbmNlX2hycykNCnNoYXBpcm8udGVzdChuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZV9ocnMpDQpzaGFwaXJvLnRlc3QobmV1dHJhbF9wZWVyX2luZmx1ZW5jZV9ocnMpDQpgYGANCg0KVGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3dzIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBmb3Igc3R1ZGVudHMgd2l0aCBuZWdhdGl2ZSBwZWVyIGluZmx1ZW5jZSwgYnV0IG5vdCBmb3Igc3R1ZGVudHMgd2l0aCBuZXV0cmFsIGFuZCBwb3NpdGl2ZSBwZWVyIGluZmx1ZW5jZS4gV2Ugd2lsbCBub3cgdXNlIEtydXNrYWwtV2FsbGlzIHRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGVlciBpbmZsdWVuY2UgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgS3J1c2thbC1XYWxsaXMgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgcGVlciBpbmZsdWVuY2UNCmtydXNrYWwudGVzdChIb3Vyc19TdHVkaWVkIH4gUGVlcl9JbmZsdWVuY2UsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydXNrYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHBlZXIgaW5mbHVlbmNlIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2YgcGVlciBpbmZsdWVuY2UgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgQ2hpLXNxdWFyZSB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBwZWVyIGluZmx1ZW5jZQ0KdGFibGVfcGVlcl9pbmZsdWVuY2VfaG91cnMgPC0gdGFibGUoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWQsIHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSkNCmNoaXNxLnRlc3QodGFibGVfcGVlcl9pbmZsdWVuY2VfaG91cnMpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBwZWVyIGluZmx1ZW5jZSBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCiMjIyBBdmVyYWdlIE51bWJlciBvZiBIb3VycyBTdHVkZW50cyBTdHVkeSBwZXIgV2VlayAoTGVhcm5pbmcgRGlzYWJpbGl0eSBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0eS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KbGVhcm5pbmdfZGlzYWJpbGl0aWVzX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJZZXMiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIlllcyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJExlYXJuaW5nX0Rpc2FiaWxpdGllcyA9PSAiWWVzIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpub19sZWFybmluZ19kaXNhYmlsaXRpZXNfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJObyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJExlYXJuaW5nX0Rpc2FiaWxpdGllcyA9PSAiTm8iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IGxlYXJuaW5nIGRpc2FiaWxpdHkNCnN1bW1hcnkobGVhcm5pbmdfZGlzYWJpbGl0aWVzX2hycykNCnN1bW1hcnkobm9fbGVhcm5pbmdfZGlzYWJpbGl0aWVzX2hycykNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBsZWFybmluZyBkaXNhYmlsaXR5IHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0eS4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiB0LXRlc3QuDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgbGVhcm5pbmcgZGlzYWJpbGl0eQ0KcGFyKG1mcm93ID0gYygxLCAyKSkNCmhpc3QobGVhcm5pbmdfZGlzYWJpbGl0aWVzX2hycywgbWFpbiA9ICJMZWFybmluZyBEaXNhYmlsaXRpZXMiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChub19sZWFybmluZ19kaXNhYmlsaXRpZXNfaHJzLCBtYWluID0gIk5vIExlYXJuaW5nIERpc2FiaWxpdGllcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgdC10ZXN0DQpzaGFwaXJvLnRlc3QobGVhcm5pbmdfZGlzYWJpbGl0aWVzX2hycykNCnNoYXBpcm8udGVzdChub19sZWFybmluZ19kaXNhYmlsaXRpZXNfaHJzKQ0KYGBgDQoNClRoZSBTaGFwaXJvLVdpbGsgdGVzdCBzaG93cyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgYXBwcm94aW1hdGVseSBub3JtYWwgZm9yIHN0dWRlbnRzIHdpdGggbGVhcm5pbmcgZGlzYWJpbGl0aWVzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gSG93ZXZlciwgdGhlIGRpc3RyaWJ1dGlvbiBmb3Igc3R1ZGVudHMgd2l0aG91dCBsZWFybmluZyBkaXNhYmlsaXRpZXMgaXMgc2xpZ2h0bHkgc2tld2VkLCB3aXRoIGEgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNS4gV2Ugd2lsbCBub3cgdXNlIHdpbGNveG9uIHJhbmsgc3VtIHRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0eS4NCg0KYGBge3J9DQojIFdpbGNveG9uIHJhbmsgc3VtIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IGxlYXJuaW5nIGRpc2FiaWxpdHkNCndpbGNveC50ZXN0KGxlYXJuaW5nX2Rpc2FiaWxpdGllc19ocnMsIG5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllc19ocnMpDQpgYGANCg0KVGhlIFdpbGNveG9uIHJhbmsgc3VtIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBsZWFybmluZyBkaXNhYmlsaXR5LCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBsZWFybmluZyBkaXNhYmlsaXRpZXMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBzdHVkeSBob3VycyBhcmUgaW5kZXBlbmRlbnQgb2YgbGVhcm5pbmcgZGlzYWJpbGl0eS4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgbGVhcm5pbmcgZGlzYWJpbGl0eQ0KdGFibGVfbGVhcm5pbmdfZGlzYWJpbGl0aWVzX2hvdXJzIDwtIHRhYmxlKHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkLCBzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzKQ0KY2hpc3EudGVzdCh0YWJsZV9sZWFybmluZ19kaXNhYmlsaXRpZXNfaG91cnMpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiBsZWFybmluZyBkaXNhYmlsaXRpZXMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBsZWFybmluZyBkaXNhYmlsaXRpZXMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChQYXJlbnRhbCBFZHVjYXRpb24gTGV2ZWwgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmhpZ2hfc2Nob29sX2VkdWNhdGlvbl9ocnMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiSGlnaCBTY2hvb2wiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkhpZ2ggU2Nob29sIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJIaWdoIFNjaG9vbCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KY29sbGVnZV9lZHVjYXRpb25faHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCnBvc3RncmFkdWF0ZV9lZHVjYXRpb25faHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIlBvc3RncmFkdWF0ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiUG9zdGdyYWR1YXRlIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJQb3N0Z3JhZHVhdGUiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbA0Kc3VtbWFyeShoaWdoX3NjaG9vbF9lZHVjYXRpb25faHJzKQ0Kc3VtbWFyeShjb2xsZWdlX2VkdWNhdGlvbl9ocnMpDQpzdW1tYXJ5KHBvc3RncmFkdWF0ZV9lZHVjYXRpb25faHJzKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMuIEJ1dCBmaXJzdCwgd2UgbmVlZCB0byBjaGVjayB0aGUgYXNzdW1wdGlvbnMgb2YgQU5PVkEuDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX3NjaG9vbF9lZHVjYXRpb25faHJzLCBtYWluID0gIkhpZ2ggU2Nob29sIEVkdWNhdGlvbiIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGNvbGxlZ2VfZWR1Y2F0aW9uX2hycywgbWFpbiA9ICJDb2xsZWdlIEVkdWNhdGlvbiIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KHBvc3RncmFkdWF0ZV9lZHVjYXRpb25faHJzLCBtYWluID0gIlBvc3RncmFkdWF0ZSBFZHVjYXRpb24iLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QoaGlnaF9zY2hvb2xfZWR1Y2F0aW9uX2hycykNCnNoYXBpcm8udGVzdChjb2xsZWdlX2VkdWNhdGlvbl9ocnMpDQpzaGFwaXJvLnRlc3QocG9zdGdyYWR1YXRlX2VkdWNhdGlvbl9ocnMpDQpgYGANCg0KQWxsIHRocmVlIGhpc3RvZ3JhbXMgYW5kIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBzaG93IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBmb3IgYWxsIHN0dWRlbnRzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscy4NCg0KYGBge3J9DQojIEFOT1ZBIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbA0KYW5vdmFfcGFyZW50YWxfZWR1Y2F0aW9uX2xldmVsIDwtIGFvdihIb3Vyc19TdHVkaWVkIH4gUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0Kc3VtbWFyeShhbm92YV9wYXJlbnRhbF9lZHVjYXRpb25fbGV2ZWwpDQpgYGANCg0KVGhlIEFOT1ZBIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzIGRvIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgc3R1ZHkgaG91cnMgYXJlIGluZGVwZW5kZW50IG9mIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbA0KdGFibGVfcGFyZW50YWxfZWR1Y2F0aW9uX2hvdXJzIDwtIHRhYmxlKHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkLCBzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsKQ0KY2hpc3EudGVzdCh0YWJsZV9wYXJlbnRhbF9lZHVjYXRpb25faG91cnMpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBmdXJ0aGVyIGNvbmZpcm1zIHRoYXQgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKERpc3RhbmNlIGZyb20gSG9tZSBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gdGhlIGRpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCm5lYXJfZGlzdGFuY2VfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIk5lYXIiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIk5lYXIiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIk5lYXIiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm1vZGVyYXRlX2Rpc3RhbmNlX2hycyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJNb2RlcmF0ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiTW9kZXJhdGUiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIk1vZGVyYXRlIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpmYXJfZGlzdGFuY2VfaHJzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIkZhciJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiRmFyIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJGYXIiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IGRpc3RhbmNlIGZyb20gaG9tZSAoTmVhciwgTW9kZXJhdGUsIEZhcg0Kc3VtbWFyeShuZWFyX2Rpc3RhbmNlX2hycykNCnN1bW1hcnkobW9kZXJhdGVfZGlzdGFuY2VfaHJzKQ0Kc3VtbWFyeShmYXJfZGlzdGFuY2VfaHJzKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHRoZSBkaXN0YW5jZSBmcm9tIGhvbWUgdG8gc2Nob29sIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSBBTk9WQSB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbC4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBkaXN0YW5jZSBmcm9tIGhvbWUNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KG5lYXJfZGlzdGFuY2VfaHJzLCBtYWluID0gIk5lYXIgRGlzdGFuY2UgZnJvbSBIb21lIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobW9kZXJhdGVfZGlzdGFuY2VfaHJzLCBtYWluID0gIk1vZGVyYXRlIERpc3RhbmNlIGZyb20gSG9tZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGZhcl9kaXN0YW5jZV9ocnMsIG1haW4gPSAiRmFyIERpc3RhbmNlIGZyb20gSG9tZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChuZWFyX2Rpc3RhbmNlX2hycykNCnNoYXBpcm8udGVzdChtb2RlcmF0ZV9kaXN0YW5jZV9ocnMpDQpzaGFwaXJvLnRlc3QoZmFyX2Rpc3RhbmNlX2hycykNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvd3MgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBzdHVkZW50cyB3aXRoIGZhciBkaXN0YW5jZSBmcm9tIGhvbWUsIGJ1dCBub3QgZm9yIHN0dWRlbnRzIHdpdGggbmVhciBhbmQgbW9kZXJhdGUgZGlzdGFuY2UgZnJvbSBob21lLiBXZSB3aWxsIG5vdyB1c2UgS3J1a3NhbC1XYWxsaXMgdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbC4NCg0KYGBge3J9DQojIEtydXNrYWwtV2FsbGlzIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IGRpc3RhbmNlIGZyb20gaG9tZQ0Ka3J1c2thbC50ZXN0KEhvdXJzX1N0dWRpZWQgfiBEaXN0YW5jZV9mcm9tX0hvbWUsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydXNrYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbCwgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlIGRpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQpOb3cgd2UgdXNlIENoaS1zcXVhcmUgdGVzdCB0byBjaGVjayB3aGV0aGVyIHN0dWR5IGhvdXJzIGFyZSBpbmRlcGVuZGVudCBvZiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbC4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgZGlzdGFuY2UgZnJvbSBob21lDQp0YWJsZV9kaXN0YW5jZV9mcm9tX2hvbWVfaG91cnMgPC0gdGFibGUoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWQsIHN0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUpDQpjaGlzcS50ZXN0KHRhYmxlX2Rpc3RhbmNlX2Zyb21faG9tZV9ob3VycykNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgc3R1ZHkgaG91cnMgYXJlIGluZGVwZW5kZW50IG9mIHRoZSBkaXN0YW5jZSBmcm9tIGhvbWUgdG8gc2Nob29sLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBmdXJ0aGVyIGNvbmZpcm1zIHRoYXQgdGhlIGRpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyMgU3VtbWFyeSBvZiBBdmVyYWdlIE51bWJlciBvZiBIb3VycyBTdHVkZW50cyBTdHVkeSBwZXIgV2Vlaw0KDQpCYXNlZCBvbiBvdXIgYW5hbHlzaXMsIHdlIGZvdW5kIHRoYXQgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGlzIG5vdCBzaWduaWZpY2FudGx5IGluZmx1ZW5jZWQgYnkgdGhlIGZvbGxvd2luZyBmYWN0b3JzOg0KDQoxLiBQYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQoyLiBNb3RpdmF0aW9uIGxldmVscw0KMy4gQWNjZXNzIHRvIHJlc291cmNlcw0KNC4gUGFyZW50YWwgaW52b2x2ZW1lbnQNCjUuIFBlZXIgaW5mbHVlbmNlDQo2LiBMZWFybmluZyBkaXNhYmlsaXRpZXMNCjcuIFBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMNCjguIERpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wNCg0KT3VyIGFuYWx5c2lzIGluZGljYXRlcyB0aGF0IHRoZXNlIGZhY3RvcnMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4gVGhpcyBzdWdnZXN0cyB0aGF0IHN0dWRlbnRzIGFyZSBhYmxlIHRvIGFsbG9jYXRlIGEgY29uc2lzdGVudCBhbW91bnQgb2YgdGltZSB0byBzdHVkeWluZyByZWdhcmRsZXNzIG9mIHRoZXNlIGZhY3RvcnMuIFRoaXMgaW5mb3JtYXRpb24gY2FuIGJlIHZhbHVhYmxlIGZvciBlZHVjYXRvcnMgYW5kIHBvbGljeW1ha2VycyB0byB1bmRlcnN0YW5kIHN0dWRlbnQgc3R1ZHkgaGFiaXRzIGFuZCBtYWtlIGluZm9ybWVkIGRlY2lzaW9ucyB0byBzdXBwb3J0IHN0dWRlbnQgbGVhcm5pbmcuIEhvd2V2ZXIsIGZvciBpbnRlcm5ldCBhY2Nlc3MsIHdlIGZvdW5kIHRoYXQgc3R1ZGVudHMgd2l0aCBpbnRlcm5ldCBhY2Nlc3MgdGVuZCB0byBzdHVkeSBtb3JlIGhvdXJzIHBlciB3ZWVrIGNvbXBhcmVkIHRvIHN0dWRlbnRzIHdpdGhvdXQgaW50ZXJuZXQgYWNjZXNzLiBUaGlzIHN1Z2dlc3RzIHRoYXQgaW50ZXJuZXQgYWNjZXNzIG1heSBwbGF5IGEgcm9sZSBpbiBmYWNpbGl0YXRpbmcgYWRkaXRpb25hbCBzdHVkeSB0aW1lIGZvciBzdHVkZW50cy4NCg0KIyBUaGUgdmFyaWF0aW9uIGluIGF0dGVuZGFuY2UgcmF0ZXMgYWNyb3NzIHN0dWRlbnRzDQoNCk5vdyB3ZSBhbmFseXplIHRoZSB2YXJpYXRpb24gaW4gYXR0ZW5kYW5jZSByYXRlcyBhY3Jvc3Mgc3R1ZGVudHMuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCnNhbXBsZV9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3NhbXBsZShucm93KHN0dWRlbnRfZGF0YSksIHJvdW5kKG5yb3coc3R1ZGVudF9kYXRhKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGF0dGVuZGFuY2UgcmF0ZXMNCnN1bW1hcnkoc2FtcGxlX2F0dGVuZGFuY2UpDQoNCiMgSGlzdG9ncmFtIG9mIGF0dGVuZGFuY2UgcmF0ZXMNCmhpc3Qoc2FtcGxlX2F0dGVuZGFuY2UsIG1haW4gPSAiRGlzdHJpYnV0aW9uIG9mIEF0dGVuZGFuY2UgUmF0ZXMiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQpGcm9tIHRoZSBoaXN0b2dyYW0gd2UgY2FuIHNlZSB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgYXR0ZW5kYW5jZSByYXRlcyBpcyBhcHByb3hpbWF0ZWx5IHVuaWZvcm0sIHJhbmdpbmcgZnJvbSBhcHByb3hpbWF0ZWx5ICoqYDYwJWAqKiB0byAqKmAxMDAlYCoqLiBGcm9tIHRoaXMgd2UgY2FuIHNlZSB0aGF0IGF0dGVuZGFuY2UgcmF0ZXMgYXJlIGV2ZW5seSBkaXN0cmlidXRlZCBhY3Jvc3Mgc3R1ZGVudHMuIFRoZSBhdmVyYWdlIGF0dGVuZGFuY2UgcmF0ZSBpcyBhcHByb3hpbWF0ZWx5ICoqYDc5Ljc1JWAqKiwgd2hpY2ggaXMgcmVsYXRpdmVseSBoaWdoLiBXZSBub3cgaW52ZXN0aWdhdGUgdGhlIGZhY3RvcnMgdGhhdCBtYXkgaW5mbHVlbmNlIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCiMjIyBBdHRlbmRhbmNlIFJhdGVzIGJ5IFBhcmVudGFsIEludm9sdmVtZW50DQoNCldlIHdpbGwgbm93IGV4cGxvcmUgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpoaWdoX3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkhpZ2giKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiSGlnaCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJNZWRpdW0iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTWVkaXVtIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIk1lZGl1bSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbG93X3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTG93IiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkxvdyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBwYXJlbnRhbCBpbnZvbHZlbWVudA0Kc3VtbWFyeShoaWdoX3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UpDQpzdW1tYXJ5KG1lZGl1bV9wYXJlbnRhbF9pbnZvbHZlbWVudF9hdHRlbmRhbmNlKQ0Kc3VtbWFyeShsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnRfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscy4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBhdHRlbmRhbmNlIHJhdGVzIGJ5IHBhcmVudGFsIGludm9sdmVtZW50DQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UsIG1haW4gPSAiSGlnaCBQYXJlbnRhbCBJbnZvbHZlbWVudCIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1fcGFyZW50YWxfaW52b2x2ZW1lbnRfYXR0ZW5kYW5jZSwgbWFpbiA9ICJNZWRpdW0gUGFyZW50YWwgSW52b2x2ZW1lbnQiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobG93X3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UsIG1haW4gPSAiTG93IFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgS3J1a3NhbC1XYWxsaXMgdGVzdA0Ka3J1c2thbC50ZXN0KEF0dGVuZGFuY2UgfiBQYXJlbnRhbF9JbnZvbHZlbWVudCwgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHBhcmVudGFsIGludm9sdmVtZW50IGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIGF0dGVuZGFuY2UgcmF0ZXMgYnkgcGFyZW50YWwgaW52b2x2ZW1lbnQNCnRhYmxlX3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UgPC0gdGFibGUoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2UsIHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCkNCmNoaXNxLnRlc3QodGFibGVfcGFyZW50YWxfaW52b2x2ZW1lbnRfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBmdXJ0aGVyIGNvbmZpcm1zIHRoYXQgcGFyZW50YWwgaW52b2x2ZW1lbnQgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQojIyMgQXR0ZW5kYW5jZSBSYXRlcyBieSBBY2Nlc3MgdG8gUmVzb3VyY2VzDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaGlnaF9hY2Nlc3NfdG9fcmVzb3VyY2VzX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJIaWdoIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiSGlnaCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTWVkaXVtIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTWVkaXVtIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpsb3dfYWNjZXNzX3RvX3Jlc291cmNlc19hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJMb3ciKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGF0dGVuZGFuY2UgcmF0ZXMgYnkgYWNjZXNzIHRvIHJlc291cmNlcw0Kc3VtbWFyeShoaWdoX2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSkNCnN1bW1hcnkobWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSkNCnN1bW1hcnkobG93X2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIGFjY2VzcyB0byByZXNvdXJjZXMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEtydXNrYWwtV2FsbGlzIHRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIGF0dGVuZGFuY2UgcmF0ZXMgYnkgYWNjZXNzIHRvIHJlc291cmNlcw0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QoaGlnaF9hY2Nlc3NfdG9fcmVzb3VyY2VzX2F0dGVuZGFuY2UsIG1haW4gPSAiSGlnaCBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2F0dGVuZGFuY2UsIG1haW4gPSAiTWVkaXVtIEFjY2VzcyB0byBSZXNvdXJjZXMiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobG93X2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSwgbWFpbiA9ICJMb3cgQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIEtydWtzYWwtV2FsbGlzIHRlc3QNCmtydXNrYWwudGVzdChBdHRlbmRhbmNlIH4gQWNjZXNzX3RvX1Jlc291cmNlcywgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBhY2Nlc3MgdG8gcmVzb3VyY2VzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBhY2Nlc3MgdG8gcmVzb3VyY2VzLg0KDQpgYGB7cn0NCiMgQ2hpLXNxdWFyZSB0ZXN0IGZvciBhdHRlbmRhbmNlIHJhdGVzIGJ5IGFjY2VzcyB0byByZXNvdXJjZXMNCnRhYmxlX2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSA8LSB0YWJsZShzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZSwgc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMpDQpjaGlzcS50ZXN0KHRhYmxlX2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgYWNjZXNzIHRvIHJlc291cmNlcywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgZnVydGhlciBjb25maXJtcyB0aGF0IGFjY2VzcyB0byByZXNvdXJjZXMgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQojIyMgQXR0ZW5kYW5jZSBSYXRlcyBieSBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcw0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCnBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiWWVzIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIlllcyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJZZXMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhdHRlbmRhbmNlIHJhdGVzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQpzdW1tYXJ5KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9hdHRlbmRhbmNlKQ0Kc3VtbWFyeShkb19ub3RfcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2F0dGVuZGFuY2UpDQpgYGANClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgV2lsY294b24gcmFuayBzdW0gdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMuDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2YgYXR0ZW5kYW5jZSByYXRlcyBieSBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcw0KcGFyKG1mcm93ID0gYygxLCAyKSkNCmhpc3QocGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2F0dGVuZGFuY2UsIG1haW4gPSAiRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QoZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9hdHRlbmRhbmNlLCBtYWluID0gIk5vIEV4dHJhY3VycmljdWxhciBBY3Rpdml0aWVzIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgV2lsY294b24gcmFuayBzdW0gdGVzdA0Kd2lsY294LnRlc3QocGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2F0dGVuZGFuY2UsIGRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgV2lsY294b24gcmFuayBzdW0gdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLg0KDQpgYGB7cn0NCiMgQ2hpLXNxdWFyZSB0ZXN0IGZvciBhdHRlbmRhbmNlIHJhdGVzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQp0YWJsZV9leHRyYWN1cnJpY3VsYXJfYWN0aXZpdGllc19hdHRlbmRhbmNlIDwtIHRhYmxlKHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlLCBzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMpDQpjaGlzcS50ZXN0KHRhYmxlX2V4dHJhY3VycmljdWxhcl9hY3Rpdml0aWVzX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IGF0dGVuZGFuY2UgcmF0ZXMgYXJlIGluZGVwZW5kZW50IG9mIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMjIEF0dGVuZGFuY2UgUmF0ZXMgYnkgTW90aXZhdGlvbmFsIExldmVsDQoNCk5leHQsIHdlIGV4cGxvcmUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBtb3RpdmF0aW9uYWwgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpoaWdoX21vdGl2YXRpb25fYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiSGlnaCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkhpZ2giKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJIaWdoIikqc2FtcGxlX2ZyYWN0aW9uKSldDQptZWRpdW1fbW90aXZhdGlvbl9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJNZWRpdW0iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJNZWRpdW0iKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJNZWRpdW0iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmxvd19tb3RpdmF0aW9uX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkxvdyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkxvdyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBtb3RpdmF0aW9uYWwgbGV2ZWxzDQpzdW1tYXJ5KGhpZ2hfbW90aXZhdGlvbl9hdHRlbmRhbmNlKQ0Kc3VtbWFyeShtZWRpdW1fbW90aXZhdGlvbl9hdHRlbmRhbmNlKQ0Kc3VtbWFyeShsb3dfbW90aXZhdGlvbl9hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gbW90aXZhdGlvbmFsIGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIG1vdGl2YXRpb25hbCBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2YgYXR0ZW5kYW5jZSByYXRlcyBieSBtb3RpdmF0aW9uYWwgbGV2ZWxzDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX21vdGl2YXRpb25fYXR0ZW5kYW5jZSwgbWFpbiA9ICJIaWdoIE1vdGl2YXRpb24gTGV2ZWwiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX21vdGl2YXRpb25fYXR0ZW5kYW5jZSwgbWFpbiA9ICJNZWRpdW0gTW90aXZhdGlvbiBMZXZlbCIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChsb3dfbW90aXZhdGlvbl9hdHRlbmRhbmNlLCBtYWluID0gIkxvdyBNb3RpdmF0aW9uIExldmVsIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgS3J1a3NhbC1XYWxsaXMgdGVzdA0Ka3J1c2thbC50ZXN0KEF0dGVuZGFuY2UgfiBNb3RpdmF0aW9uX0xldmVsLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIG1vdGl2YXRpb25hbCBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IG1vdGl2YXRpb24gbGV2ZWxzIGRvIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgbW90aXZhdGlvbmFsIGxldmVscy4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBtb3RpdmF0aW9uYWwgbGV2ZWxzDQp0YWJsZV9tb3RpdmF0aW9uX2xldmVsX2F0dGVuZGFuY2UgPC0gdGFibGUoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2UsIHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsKQ0KY2hpc3EudGVzdCh0YWJsZV9tb3RpdmF0aW9uX2xldmVsX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IGF0dGVuZGFuY2UgcmF0ZXMgYXJlIGluZGVwZW5kZW50IG9mIG1vdGl2YXRpb25hbCBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBtb3RpdmF0aW9uIGxldmVscyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQojIyMgQXR0ZW5kYW5jZSBSYXRlcyBieSBJbnRlcm5ldCBBY2Nlc3MNCg0KTmV4dCwgd2UgZXhwbG9yZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIGludGVybmV0IGFjY2Vzcy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaW50ZXJuZXRfYWNjZXNzX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiWWVzIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkSW50ZXJuZXRfQWNjZXNzID09ICJZZXMiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIlllcyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0Kbm9faW50ZXJuZXRfYWNjZXNzX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiTm8iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIk5vIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkSW50ZXJuZXRfQWNjZXNzID09ICJObyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBpbnRlcm5ldCBhY2Nlc3MNCnN1bW1hcnkoaW50ZXJuZXRfYWNjZXNzX2F0dGVuZGFuY2UpDQpzdW1tYXJ5KG5vX2ludGVybmV0X2FjY2Vzc19hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSBXaWxjb3hvbiByYW5rIHN1bSB0ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIGF0dGVuZGFuY2UgcmF0ZXMgYnkgaW50ZXJuZXQgYWNjZXNzDQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChpbnRlcm5ldF9hY2Nlc3NfYXR0ZW5kYW5jZSwgbWFpbiA9ICJJbnRlcm5ldCBBY2Nlc3MiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3Qobm9faW50ZXJuZXRfYWNjZXNzX2F0dGVuZGFuY2UsIG1haW4gPSAiTm8gSW50ZXJuZXQgQWNjZXNzIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgV2lsY294b24gcmFuayBzdW0gdGVzdA0Kd2lsY294LnRlc3QoaW50ZXJuZXRfYWNjZXNzX2F0dGVuZGFuY2UsIG5vX2ludGVybmV0X2FjY2Vzc19hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBXaWxjb3hvbiByYW5rIHN1bSB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIGludGVybmV0IGFjY2Vzcywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgaW50ZXJuZXQgYWNjZXNzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBpbnRlcm5ldCBhY2Nlc3MuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIGF0dGVuZGFuY2UgcmF0ZXMgYnkgaW50ZXJuZXQgYWNjZXNzDQp0YWJsZV9pbnRlcm5ldF9hY2Nlc3NfYXR0ZW5kYW5jZSA8LSB0YWJsZShzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZSwgc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcykNCmNoaXNxLnRlc3QodGFibGVfaW50ZXJuZXRfYWNjZXNzX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIENoaS1zcXVhcmUgdGVzdCBzaG93cyB0aGF0IGF0dGVuZGFuY2UgcmF0ZXMgYXJlIGluZGVwZW5kZW50IG9mIGludGVybmV0IGFjY2Vzcywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgZnVydGhlciBjb25maXJtcyB0aGF0IGludGVybmV0IGFjY2VzcyBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCiMjIyBBdHRlbmRhbmNlIFJhdGVzIGJ5IEZhbWlseSBJbmNvbWUgQ2F0ZWdvcnkNCg0KTmV4dCwgd2UgZXhwbG9yZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIGZhbWlseSBpbmNvbWUgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpsb3dfZmFtaWx5X2luY29tZV9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm1lZGl1bV9mYW1pbHlfaW5jb21lX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIk1lZGl1bSIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIk1lZGl1bSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KaGlnaF9mYW1pbHlfaW5jb21lX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJIaWdoIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiSGlnaCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBmYW1pbHkgaW5jb21lDQpzdW1tYXJ5KGhpZ2hfZmFtaWx5X2luY29tZV9hdHRlbmRhbmNlKQ0Kc3VtbWFyeShtZWRpdW1fZmFtaWx5X2luY29tZV9hdHRlbmRhbmNlKQ0Kc3VtbWFyeShsb3dfZmFtaWx5X2luY29tZV9hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gZmFtaWx5IGluY29tZSBsZXZlbHMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEtydXNrYWwtV2FsbGlzIHRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscy4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBhdHRlbmRhbmNlIHJhdGVzIGJ5IGZhbWlseSBpbmNvbWUNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGxvd19mYW1pbHlfaW5jb21lX2F0dGVuZGFuY2UsIG1haW4gPSAiTG93IEZhbWlseSBJbmNvbWUiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX2ZhbWlseV9pbmNvbWVfYXR0ZW5kYW5jZSwgbWFpbiA9ICJNZWRpdW0gRmFtaWx5IEluY29tZSIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChoaWdoX2ZhbWlseV9pbmNvbWVfYXR0ZW5kYW5jZSwgbWFpbiA9ICJIaWdoIEZhbWlseSBJbmNvbWUiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBLcnVrc2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsLnRlc3QoQXR0ZW5kYW5jZSB+IEZhbWlseV9JbmNvbWUsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydWtzYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gZmFtaWx5IGluY29tZSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IGZhbWlseSBpbmNvbWUgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQpOb3cgd2UgdXNlIENoaS1zcXVhcmUgdGVzdCB0byBjaGVjayB3aGV0aGVyIGF0dGVuZGFuY2UgcmF0ZXMgYXJlIGluZGVwZW5kZW50IG9mIGZhbWlseSBpbmNvbWUgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgQ2hpLXNxdWFyZSB0ZXN0IGZvciBhdHRlbmRhbmNlIHJhdGVzIGJ5IGZhbWlseSBpbmNvbWUNCnRhYmxlX2ZhbWlseV9pbmNvbWVfYXR0ZW5kYW5jZSA8LSB0YWJsZShzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZSwgc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUpDQpjaGlzcS50ZXN0KHRhYmxlX2ZhbWlseV9pbmNvbWVfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgZmFtaWx5IGluY29tZSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBmYW1pbHkgaW5jb21lIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMjIEF0dGVuZGFuY2UgUmF0ZXMgYnkgVGVhY2hlciBRdWFsaXR5IENhdGVnb3J5DQoNCk5leHQsIHdlIGV4cGxvcmUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpsb3dfdGVhY2hlcl9xdWFsaXR5X2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJMb3ciKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkxvdyIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KbWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTWVkaXVtIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJNZWRpdW0iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmhpZ2hfdGVhY2hlcl9xdWFsaXR5X2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiSGlnaCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiSGlnaCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiSGlnaCIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSB0ZWFjaGVyIHF1YWxpdHkNCnN1bW1hcnkobG93X3RlYWNoZXJfcXVhbGl0eV9hdHRlbmRhbmNlKQ0Kc3VtbWFyeShtZWRpdW1fdGVhY2hlcl9xdWFsaXR5X2F0dGVuZGFuY2UpDQpzdW1tYXJ5KGhpZ2hfdGVhY2hlcl9xdWFsaXR5X2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gdGVhY2hlciBxdWFsaXR5IGxldmVscy4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBhdHRlbmRhbmNlIHJhdGVzIGJ5IHRlYWNoZXIgcXVhbGl0eQ0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QobG93X3RlYWNoZXJfcXVhbGl0eV9hdHRlbmRhbmNlLCBtYWluID0gIkxvdyBUZWFjaGVyIFF1YWxpdHkiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX3RlYWNoZXJfcXVhbGl0eV9hdHRlbmRhbmNlLCBtYWluID0gIk1lZGl1bSBUZWFjaGVyIFF1YWxpdHkiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QoaGlnaF90ZWFjaGVyX3F1YWxpdHlfYXR0ZW5kYW5jZSwgbWFpbiA9ICJIaWdoIFRlYWNoZXIgUXVhbGl0eSIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIEtydWtzYWwtV2FsbGlzIHRlc3QNCmtydXNrYWwudGVzdChBdHRlbmRhbmNlIH4gVGVhY2hlcl9RdWFsaXR5LCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVrc2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHRlYWNoZXIgcXVhbGl0eSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHRlYWNoZXIgcXVhbGl0eSBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgdGVhY2hlciBxdWFsaXR5IGxldmVscy4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSB0ZWFjaGVyIHF1YWxpdHkNCnRhYmxlX3RlYWNoZXJfcXVhbGl0eV9hdHRlbmRhbmNlIDwtIHRhYmxlKHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlLCBzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5KQ0KY2hpc3EudGVzdCh0YWJsZV90ZWFjaGVyX3F1YWxpdHlfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgdGVhY2hlciBxdWFsaXR5IGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgZnVydGhlciBjb25maXJtcyB0aGF0IHRlYWNoZXIgcXVhbGl0eSBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCiMjIyBBdHRlbmRhbmNlIFJhdGVzIGJ5IFNjaG9vbCBUeXBlIENhdGVnb3J5DQoNCk5leHQsIHdlIGV4cGxvcmUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBzY2hvb2wgdHlwZS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KcHVibGljX3NjaG9vbF9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRTY2hvb2xfVHlwZSA9PSAiUHVibGljIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlB1YmxpYyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQdWJsaWMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCnByaXZhdGVfc2Nob29sX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQcml2YXRlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlByaXZhdGUiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRTY2hvb2xfVHlwZSA9PSAiUHJpdmF0ZSIpKnNhbXBsZV9mcmFjdGlvbikpXQ0KDQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBzY2hvb2wgdHlwZQ0Kc3VtbWFyeShwdWJsaWNfc2Nob29sX2F0dGVuZGFuY2UpDQpzdW1tYXJ5KHByaXZhdGVfc2Nob29sX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBzY2hvb2wgdHlwZSBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgV2lsY294b24gcmFuayBzdW0gdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHNjaG9vbCB0eXBlLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIGF0dGVuZGFuY2UgcmF0ZXMgYnkgc2Nob29sIHR5cGUNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpoaXN0KHB1YmxpY19zY2hvb2xfYXR0ZW5kYW5jZSwgbWFpbiA9ICJQdWJsaWMgU2Nob29sIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KHByaXZhdGVfc2Nob29sX2F0dGVuZGFuY2UsIG1haW4gPSAiUHJpdmF0ZSBTY2hvb2wiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBXaWxjb3hvbiByYW5rIHN1bSB0ZXN0DQp3aWxjb3gudGVzdChwdWJsaWNfc2Nob29sX2F0dGVuZGFuY2UsIHByaXZhdGVfc2Nob29sX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIFdpbGNveG9uIHJhbmsgc3VtIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gc2Nob29sIHR5cGUsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHNjaG9vbCB0eXBlIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KTm93IHdlIHVzZSBDaGktc3F1YXJlIHRlc3QgdG8gY2hlY2sgd2hldGhlciBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBzY2hvb2wgdHlwZS4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBzY2hvb2wgdHlwZQ0KdGFibGVfc2Nob29sX3R5cGVfYXR0ZW5kYW5jZSA8LSB0YWJsZShzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZSwgc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlKQ0KY2hpc3EudGVzdCh0YWJsZV9zY2hvb2xfdHlwZV9hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBDaGktc3F1YXJlIHRlc3Qgc2hvd3MgdGhhdCBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBzY2hvb2wgdHlwZSwgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgZnVydGhlciBjb25maXJtcyB0aGF0IHNjaG9vbCB0eXBlIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMjIEF0dGVuZGFuY2UgUmF0ZXMgYnkgUGVlciBJbmZsdWVuY2UgQ2F0ZWdvcnkNCg0KTmV4dCwgd2UgZXhwbG9yZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KcG9zaXRpdmVfcGVlcl9pbmZsdWVuY2VfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIlBvc2l0aXZlIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZV9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmVnYXRpdmUiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmVnYXRpdmUiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmVnYXRpdmUiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm5ldXRyYWxfcGVlcl9pbmZsdWVuY2VfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIk5ldXRyYWwiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmV1dHJhbCIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZXV0cmFsIikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhdHRlbmRhbmNlIHJhdGVzIGJ5IHBlZXIgaW5mbHVlbmNlDQpzdW1tYXJ5KHBvc2l0aXZlX3BlZXJfaW5mbHVlbmNlX2F0dGVuZGFuY2UpDQpzdW1tYXJ5KG5lZ2F0aXZlX3BlZXJfaW5mbHVlbmNlX2F0dGVuZGFuY2UpDQpzdW1tYXJ5KG5ldXRyYWxfcGVlcl9pbmZsdWVuY2VfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgS3J1a3NhbC1XYWxsaXMgdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscy4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBhdHRlbmRhbmNlIHJhdGVzIGJ5IHBlZXIgaW5mbHVlbmNlDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChwb3NpdGl2ZV9wZWVyX2luZmx1ZW5jZV9hdHRlbmRhbmNlLCBtYWluID0gIlBvc2l0aXZlIFBlZXIgSW5mbHVlbmNlIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG5lZ2F0aXZlX3BlZXJfaW5mbHVlbmNlX2F0dGVuZGFuY2UsIG1haW4gPSAiTmVnYXRpdmUgUGVlciBJbmZsdWVuY2UiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobmV1dHJhbF9wZWVyX2luZmx1ZW5jZV9hdHRlbmRhbmNlLCBtYWluID0gIk5ldXRyYWwgUGVlciBJbmZsdWVuY2UiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBLcnVrc2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsLnRlc3QoQXR0ZW5kYW5jZSB+IFBlZXJfSW5mbHVlbmNlLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVrc2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgcGVlciBpbmZsdWVuY2UgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQpOb3cgd2UgdXNlIENoaS1zcXVhcmUgdGVzdCB0byBjaGVjayB3aGV0aGVyIGF0dGVuZGFuY2UgcmF0ZXMgYXJlIGluZGVwZW5kZW50IG9mIHBlZXIgaW5mbHVlbmNlIGxldmVscy4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBwZWVyIGluZmx1ZW5jZQ0KdGFibGVfcGVlcl9pbmZsdWVuY2VfYXR0ZW5kYW5jZSA8LSB0YWJsZShzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZSwgc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlKQ0KY2hpc3EudGVzdCh0YWJsZV9wZWVyX2luZmx1ZW5jZV9hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBDaGktc3F1YXJlIHRlc3Qgc2hvd3MgdGhhdCBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBwZWVyIGluZmx1ZW5jZSBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCiMjIyBBdHRlbmRhbmNlIFJhdGVzIGJ5IExlYXJuaW5nIERpc2FiaWxpdHkgQ2F0ZWdvcnkNCg0KTmV4dCwgd2UgZXhwbG9yZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIGxlYXJuaW5nIGRpc2FiaWxpdHkuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmxlYXJuaW5nX2Rpc2FiaWxpdGllc19hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJExlYXJuaW5nX0Rpc2FiaWxpdGllcyA9PSAiWWVzIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJZZXMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCm5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllc19hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJObyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJExlYXJuaW5nX0Rpc2FiaWxpdGllcyA9PSAiTm8iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGF0dGVuZGFuY2UgcmF0ZXMgYnkgbGVhcm5pbmcgZGlzYWJpbGl0eQ0Kc3VtbWFyeShsZWFybmluZ19kaXNhYmlsaXRpZXNfYXR0ZW5kYW5jZSkNCnN1bW1hcnkobm9fbGVhcm5pbmdfZGlzYWJpbGl0aWVzX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBsZWFybmluZyBkaXNhYmlsaXR5IHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0eS4NCg0KYGBge3J9DQojIEhpc3RvZ3JhbSBvZiBhdHRlbmRhbmNlIHJhdGVzIGJ5IGxlYXJuaW5nIGRpc2FiaWxpdHkNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpoaXN0KGxlYXJuaW5nX2Rpc2FiaWxpdGllc19hdHRlbmRhbmNlLCBtYWluID0gIkxlYXJuaW5nIERpc2FiaWxpdGllcyIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChub19sZWFybmluZ19kaXNhYmlsaXRpZXNfYXR0ZW5kYW5jZSwgbWFpbiA9ICJObyBMZWFybmluZyBEaXNhYmlsaXRpZXMiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBXaWxjb3hvbiByYW5rIHN1bSB0ZXN0DQp3aWxjb3gudGVzdChsZWFybmluZ19kaXNhYmlsaXRpZXNfYXR0ZW5kYW5jZSwgbm9fbGVhcm5pbmdfZGlzYWJpbGl0aWVzX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIFdpbGNveG9uIHJhbmsgc3VtIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0eSwgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgbGVhcm5pbmcgZGlzYWJpbGl0aWVzIGRvIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgbGVhcm5pbmcgZGlzYWJpbGl0aWVzLg0KDQpgYGB7cn0NCiMgQ2hpLXNxdWFyZSB0ZXN0IGZvciBhdHRlbmRhbmNlIHJhdGVzIGJ5IGxlYXJuaW5nIGRpc2FiaWxpdGllcw0KdGFibGVfbGVhcm5pbmdfZGlzYWJpbGl0aWVzX2F0dGVuZGFuY2UgPC0gdGFibGUoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2UsIHN0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMpDQpjaGlzcS50ZXN0KHRhYmxlX2xlYXJuaW5nX2Rpc2FiaWxpdGllc19hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBDaGktc3F1YXJlIHRlc3Qgc2hvd3MgdGhhdCBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBsZWFybmluZyBkaXNhYmlsaXRpZXMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGZ1cnRoZXIgY29uZmlybXMgdGhhdCBsZWFybmluZyBkaXNhYmlsaXRpZXMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMjIEF0dGVuZGFuY2UgUmF0ZXMgYnkgUGFyZW50YWwgRWR1Y2F0aW9uIExldmVsIENhdGVnb3J5DQoNCk5leHQsIHdlIGV4cGxvcmUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpoaWdoX3NjaG9vbF9lZHVjYXRpb25fYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJIaWdoIFNjaG9vbCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiSGlnaCBTY2hvb2wiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkhpZ2ggU2Nob29sIikqc2FtcGxlX2ZyYWN0aW9uKSldDQpjb2xsZWdlX2VkdWNhdGlvbl9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCnBvc3RncmFkdWF0ZV9lZHVjYXRpb25fYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJQb3N0Z3JhZHVhdGUiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIlBvc3RncmFkdWF0ZSIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiUG9zdGdyYWR1YXRlIikqc2FtcGxlX2ZyYWN0aW9uKSldDQoNCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhdHRlbmRhbmNlIHJhdGVzIGJ5IHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbA0Kc3VtbWFyeShoaWdoX3NjaG9vbF9lZHVjYXRpb25fYXR0ZW5kYW5jZSkNCnN1bW1hcnkoY29sbGVnZV9lZHVjYXRpb25fYXR0ZW5kYW5jZSkNCnN1bW1hcnkocG9zdGdyYWR1YXRlX2VkdWNhdGlvbl9hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgS3J1c2thbC1XYWxsaXMgdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2YgYXR0ZW5kYW5jZSByYXRlcyBieSBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWwNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfc2Nob29sX2VkdWNhdGlvbl9hdHRlbmRhbmNlLCBtYWluID0gIkhpZ2ggU2Nob29sIEVkdWNhdGlvbiIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChjb2xsZWdlX2VkdWNhdGlvbl9hdHRlbmRhbmNlLCBtYWluID0gIkNvbGxlZ2UgRWR1Y2F0aW9uIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KHBvc3RncmFkdWF0ZV9lZHVjYXRpb25fYXR0ZW5kYW5jZSwgbWFpbiA9ICJQb3N0Z3JhZHVhdGUgRWR1Y2F0aW9uIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgS3J1c2thbC1XYWxsaXMgdGVzdA0Ka3J1c2thbC50ZXN0KEF0dGVuZGFuY2UgfiBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydXNrYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQpOb3cgd2UgdXNlIENoaS1zcXVhcmUgdGVzdCB0byBjaGVjayB3aGV0aGVyIGF0dGVuZGFuY2UgcmF0ZXMgYXJlIGluZGVwZW5kZW50IG9mIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBDaGktc3F1YXJlIHRlc3QgZm9yIGF0dGVuZGFuY2UgcmF0ZXMgYnkgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscw0KdGFibGVfcGFyZW50YWxfZWR1Y2F0aW9uX2F0dGVuZGFuY2UgPC0gdGFibGUoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2UsIHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwpDQpjaGlzcS50ZXN0KHRhYmxlX3BhcmVudGFsX2VkdWNhdGlvbl9hdHRlbmRhbmNlKQ0KYGBgDQoNClRoZSBDaGktc3F1YXJlIHRlc3Qgc2hvd3MgdGhhdCBhdHRlbmRhbmNlIHJhdGVzIGFyZSBpbmRlcGVuZGVudCBvZiBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBmdXJ0aGVyIGNvbmZpcm1zIHRoYXQgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQojIyMgQXR0ZW5kYW5jZSBSYXRlcyBieSBEaXN0YW5jZSBmcm9tIEhvbWUgQ2F0ZWdvcnkNCg0KTmV4dCwgd2UgZXhwbG9yZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIGRpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCm5lYXJfZGlzdGFuY2VfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJOZWFyIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJOZWFyIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJOZWFyIikqc2FtcGxlX2ZyYWN0aW9uKSldDQptb2RlcmF0ZV9kaXN0YW5jZV9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIk1vZGVyYXRlIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJNb2RlcmF0ZSIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiTW9kZXJhdGUiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmZhcl9kaXN0YW5jZV9hdHRlbmRhbmNlIDwtIHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIkZhciJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiRmFyIiksIHJvdW5kKHN1bShzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJGYXIiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGF0dGVuZGFuY2UgcmF0ZXMgYnkgZGlzdGFuY2UgZnJvbSBob21lDQpzdW1tYXJ5KG5lYXJfZGlzdGFuY2VfYXR0ZW5kYW5jZSkNCnN1bW1hcnkobW9kZXJhdGVfZGlzdGFuY2VfYXR0ZW5kYW5jZSkNCnN1bW1hcnkoZmFyX2Rpc3RhbmNlX2F0dGVuZGFuY2UpDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBkaXN0YW5jZSBmcm9tIGhvbWUgdG8gc2Nob29sIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gZGlzdGFuY2UgZnJvbSBob21lLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIGF0dGVuZGFuY2UgcmF0ZXMgYnkgZGlzdGFuY2UgZnJvbSBob21lDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChuZWFyX2Rpc3RhbmNlX2F0dGVuZGFuY2UsIG1haW4gPSAiTmVhciBEaXN0YW5jZSBmcm9tIEhvbWUiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobW9kZXJhdGVfZGlzdGFuY2VfYXR0ZW5kYW5jZSwgbWFpbiA9ICJNb2RlcmF0ZSBEaXN0YW5jZSBmcm9tIEhvbWUiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QoZmFyX2Rpc3RhbmNlX2F0dGVuZGFuY2UsIG1haW4gPSAiRmFyIERpc3RhbmNlIGZyb20gSG9tZSIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIEtydXNrYWwtV2FsbGlzIHRlc3QNCmtydXNrYWwudGVzdChBdHRlbmRhbmNlIH4gRGlzdGFuY2VfZnJvbV9Ib21lLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHRoZSBkaXN0YW5jZSBmcm9tIGhvbWUgdG8gc2Nob29sLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbCBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXMuDQoNCk5vdyB3ZSB1c2UgQ2hpLXNxdWFyZSB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbC4NCg0KYGBge3J9DQojIENoaS1zcXVhcmUgdGVzdCBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBkaXN0YW5jZSBmcm9tIGhvbWUNCnRhYmxlX2Rpc3RhbmNlX2Zyb21faG9tZV9hdHRlbmRhbmNlIDwtIHRhYmxlKHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlLCBzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lKQ0KY2hpc3EudGVzdCh0YWJsZV9kaXN0YW5jZV9mcm9tX2hvbWVfYXR0ZW5kYW5jZSkNCmBgYA0KDQpUaGUgQ2hpLXNxdWFyZSB0ZXN0IHNob3dzIHRoYXQgYXR0ZW5kYW5jZSByYXRlcyBhcmUgaW5kZXBlbmRlbnQgb2YgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbCwgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgZnVydGhlciBjb25maXJtcyB0aGF0IHRoZSBkaXN0YW5jZSBmcm9tIGhvbWUgdG8gc2Nob29sIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMjIFN1bW1hcnkgb2YgQXR0ZW5kYW5jZSBSYXRlcw0KDQpCYXNlZCBvbiBvdXIgYW5hbHlzaXMsIHdlIGZvdW5kIHRoYXQgdGhlIGZvbGxvd2luZyBmYWN0b3JzIGRvIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIGF0dGVuZGFuY2UgcmF0ZXM6DQoNCi0gUGFyZW50YWwgSW52b2x2ZW1lbnQNCi0gQWNjZXNzIHRvIFJlc291cmNlcw0KLSBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcw0KLSBNb3RpdmF0aW9uYWwgTGV2ZWwNCi0gSW50ZXJuZXQgQWNjZXNzDQotIEZhbWlseSBJbmNvbWUNCi0gVGVhY2hlciBRdWFsaXR5DQotIFNjaG9vbCBUeXBlDQotIFBlZXIgSW5mbHVlbmNlDQotIExlYXJuaW5nIERpc2FiaWxpdGllcw0KLSBQYXJlbnRhbCBFZHVjYXRpb24gTGV2ZWwNCi0gRGlzdGFuY2UgZnJvbSBIb21lIHRvIFNjaG9vbA0KDQpUaGVzZSBmaW5kaW5ncyBzdWdnZXN0IHRoYXQgb3RoZXIgZmFjdG9ycyBub3QgaW5jbHVkZWQgaW4gdGhlIGRhdGFzZXQgbWF5IGhhdmUgYSBtb3JlIHNpZ25pZmljYW50IGltcGFjdCBvbiBzdHVkZW50IGF0dGVuZGFuY2UgcmF0ZXMuDQoNCiMgVGhlIGRpc3RyaWJ1dGlvbiBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMgYW1vbmcgc3R1ZGVudHMNCg0KTm93IHdlIGFuYWx5emUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMgYW1vbmcgc3R1ZGVudHMuDQoNCmBgYHtyfQ0KIyBDb3VudCBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMNCnRhYmxlKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCkNCg0KIyBCYXIgcGxvdCBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMNCmJhcnBsb3QodGFibGUoc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50KSwgbWFpbiA9ICJEaXN0cmlidXRpb24gb2YgUGFyZW50YWwgSW52b2x2ZW1lbnQgTGV2ZWxzIiwgeGxhYiA9ICJQYXJlbnRhbCBJbnZvbHZlbWVudCBMZXZlbHMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQpUaGUgZGlzdHJpYnV0aW9uIG9mIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBhbW9uZyBzdHVkZW50cyBpcyBhcyBmb2xsb3dzOg0KDQotICoqSGlnaCoqOiAxODM2IHN0dWRlbnRzDQotICoqTG93Kio6IDEyOTAgc3R1ZGVudHMNCi0gKipNZWRpdW0qKjogMzI1MSBzdHVkZW50cw0KDQpXZSBjYW4gc2VlIHRoYXQgdGhlIG1ham9yaXR5IG9mIHN0dWRlbnRzIGhhdmUgbWVkaXVtIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscywgZm9sbG93ZWQgYnkgaGlnaCBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMsIGFuZCBsb3cgcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLg0KDQojIyMgVGhlIGRpc3RyaWJ1dGlvbiBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMgYW1vbmcgc3R1ZGVudHMgYnkgRmFtaWx5IEluY29tZSBDYXRlZ29yeQ0KDQpXZSBub3cgZXhwbG9yZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBhbW9uZyBzdHVkZW50cyBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscy4NCg0KYGBge3J9DQojIENvdW50IG9mIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBieSBmYW1pbHkgaW5jb21lDQp0YWJsZShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQsIHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lKQ0KDQojIEJhciBwbG90IG9mIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBieSBmYW1pbHkgaW5jb21lDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KYmFycGxvdCh0YWJsZShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnRbc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIkxvdyJdKSwgbWFpbiA9ICJMb3cgRmFtaWx5IEluY29tZSIsIHhsYWIgPSAiUGFyZW50YWwgSW52b2x2ZW1lbnQgTGV2ZWxzIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpiYXJwbG90KHRhYmxlKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudFtzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTWVkaXVtIl0pLCBtYWluID0gIk1lZGl1bSBGYW1pbHkgSW5jb21lIiwgeGxhYiA9ICJQYXJlbnRhbCBJbnZvbHZlbWVudCBMZXZlbHMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmJhcnBsb3QodGFibGUoc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50W3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJIaWdoIl0pLCBtYWluID0gIkhpZ2ggRmFtaWx5IEluY29tZSIsIHhsYWIgPSAiUGFyZW50YWwgSW52b2x2ZW1lbnQgTGV2ZWxzIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KLSBUaGUgYExvdyBGYW1pbHkgSW5jb21lYCBncm91cCBoYXMgdGhlIGhpZ2hlc3QgY291bnRzIGFjcm9zcyBhbGwgbGV2ZWxzIG9mIHBhcmVudGFsIGludm9sdmVtZW50LCBzdWdnZXN0aW5nIHRoYXQgbW9yZSBzdHVkZW50cyBpbiB0aGUgZGF0YXNldCBjb21lIGZyb20gbG93LWluY29tZSBmYW1pbGllcy4NCi0gU3R1ZGVudHMgd2l0aCBNZWRpdW0gUGFyZW50YWwgSW52b2x2ZW1lbnQgYW5kIE1lZGl1bSBGYW1pbHkgSW5jb21lIGZvcm0gdGhlIGxhcmdlc3Qgc2luZ2xlIGdyb3VwICgxMzMyIHN0dWRlbnRzKS4NCi0gU3R1ZGVudHMgd2l0aCBMb3cgUGFyZW50YWwgSW52b2x2ZW1lbnQgYW5kIEhpZ2ggRmFtaWx5IEluY29tZSBmb3JtIHRoZSBzbWFsbGVzdCBzaW5nbGUgZ3JvdXAgKDI0MCBzdHVkZW50cykuDQoNCiMjIyBUaGUgZGlzdHJpYnV0aW9uIG9mIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBhbW9uZyBzdHVkZW50cyBieSBQYXJlbnRhbCBFZHVjYXRpb24gTGV2ZWwgQ2F0ZWdvcnkNCg0KV2Ugbm93IGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMgYW1vbmcgc3R1ZGVudHMgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscy4NCg0KYGBge3J9DQojIENvdW50IG9mIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBieSBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWwNCnRhYmxlKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCwgc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCkNCg0KIyBCYXIgcGxvdCBvZiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMgYnkgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KYmFycGxvdCh0YWJsZShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnRbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiSGlnaCBTY2hvb2wiXSksIG1haW4gPSAiSGlnaCBTY2hvb2wgRWR1Y2F0aW9uIiwgeGxhYiA9ICJQYXJlbnRhbCBJbnZvbHZlbWVudCBMZXZlbHMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmJhcnBsb3QodGFibGUoc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50W3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiXSksIG1haW4gPSAiQ29sbGVnZSBFZHVjYXRpb24iLCB4bGFiID0gIlBhcmVudGFsIEludm9sdmVtZW50IExldmVscyIsIHlsYWIgPSAiRnJlcXVlbmN5IiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYmFycGxvdCh0YWJsZShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnRbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiUG9zdGdyYWR1YXRlIl0pLCBtYWluID0gIlBvc3RncmFkdWF0ZSBFZHVjYXRpb24iLCB4bGFiID0gIlBhcmVudGFsIEludm9sdmVtZW50IExldmVscyIsIHlsYWIgPSAiRnJlcXVlbmN5IiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYGBgDQoNCi0gKipIaWdoIFNjaG9vbCBFZHVjYXRpb24qKjogVGhlIGxhcmdlc3QgY291bnRzIGFjcm9zcyBhbGwgbGV2ZWxzIG9mIFBhcmVudGFsIEludm9sdmVtZW50IGFyZSBvYnNlcnZlZCBpbiBmYW1pbGllcyB3aGVyZSB0aGUgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsIGlzICJIaWdoIFNjaG9vbC4iDQpGb3IgZXhhbXBsZSwgdGhlIGhpZ2hlc3QgY291bnQgaXMgZm9yIE1lZGl1bSBQYXJlbnRhbCBJbnZvbHZlbWVudCB3aXRoIHBhcmVudHMgZWR1Y2F0ZWQgYXQgdGhlIGhpZ2ggc2Nob29sIGxldmVsICgxNjM0IHN0dWRlbnRzKS4NCi0gKipQb3N0Z3JhZHVhdGUgRWR1Y2F0aW9uKio6IFRoZSBzbWFsbGVzdCBjb3VudHMgYXJlIGdlbmVyYWxseSBpbiBmYW1pbGllcyB3aGVyZSB0aGUgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsIGlzICJQb3N0Z3JhZHVhdGUsIiBzdWdnZXN0aW5nIHRoYXQgZmV3ZXIgc3R1ZGVudHMnIHBhcmVudHMgZmFsbCBpbnRvIHRoaXMgY2F0ZWdvcnkuDQpGb3IgZXhhbXBsZSwgb25seSAyNjUgc3R1ZGVudHMgd2l0aCBMb3cgUGFyZW50YWwgSW52b2x2ZW1lbnQgaGF2ZSBwYXJlbnRzIHdpdGggcG9zdGdyYWR1YXRlIGVkdWNhdGlvbi4NCi0gKipDb2xsZWdlIEVkdWNhdGlvbioqOiBDb3VudHMgYXJlIGludGVybWVkaWF0ZSwgd2l0aCBNZWRpdW0gUGFyZW50YWwgSW52b2x2ZW1lbnQgaGF2aW5nIHRoZSBoaWdoZXN0IHJlcHJlc2VudGF0aW9uICg5NjAgc3R1ZGVudHMpLg0KDQojIFRoZSBwcm9wb3J0aW9uIG9mIHN0dWRlbnRzIHdpdGggYWNjZXNzIHRvIGVkdWNhdGlvbmFsIHJlc291cmNlcw0KDQpXZSBub3cgYW5hbHl6ZSB0aGUgcHJvcG9ydGlvbiBvZiBzdHVkZW50cyB3aXRoIGFjY2VzcyB0byBlZHVjYXRpb25hbCByZXNvdXJjZXMuDQoNCmBgYHtyfQ0KIyBDb3VudCBvZiBhY2Nlc3MgdG8gcmVzb3VyY2VzDQp0YWJsZShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcykNCg0KIyBCYXIgcGxvdCBvZiBhY2Nlc3MgdG8gcmVzb3VyY2VzDQpiYXJwbG90KHRhYmxlKHN0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzKSwgbWFpbiA9ICJEaXN0cmlidXRpb24gb2YgQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiQWNjZXNzIHRvIFJlc291cmNlcyIsIHlsYWIgPSAiRnJlcXVlbmN5IiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYGBgDQoNCkhpZ2ggICAgTG93IE1lZGl1bQ0KMTkwMCAgIDEyNzQgICAzMjAzDQoNClRoZSBkaXN0cmlidXRpb24gb2YgYWNjZXNzIHRvIHJlc291cmNlcyBhbW9uZyBzdHVkZW50cyBpcyBhcyBmb2xsb3dzOg0KDQotICoqSGlnaCoqOiAxOTAwIHN0dWRlbnRzDQotICoqTG93Kio6IDEyNzQgc3R1ZGVudHMNCi0gKipNZWRpdW0qKjogMzIwMyBzdHVkZW50cw0KDQpXZSBjYW4gc2VlIHRoYXQgdGhlIG1ham9yaXR5IG9mIHN0dWRlbnRzIGhhdmUgbWVkaXVtIGFjY2VzcyB0byBlZHVjYXRpb25hbCByZXNvdXJjZXMsIGZvbGxvd2VkIGJ5IGhpZ2ggYWNjZXNzIHRvIHJlc291cmNlcywgYW5kIGxvdyBhY2Nlc3MgdG8gcmVzb3VyY2VzLg0KDQojIyMgVGhlIHByb3BvcnRpb24gb2Ygc3R1ZGVudHMgd2l0aCBhY2Nlc3MgdG8gZWR1Y2F0aW9uYWwgcmVzb3VyY2VzIGJ5IEZhbWlseSBJbmNvbWUgQ2F0ZWdvcnkNCg0KV2Ugbm93IGV4cGxvcmUgdGhlIHByb3BvcnRpb24gb2Ygc3R1ZGVudHMgd2l0aCBhY2Nlc3MgdG8gZWR1Y2F0aW9uYWwgcmVzb3VyY2VzIGJhc2VkIG9uIGZhbWlseSBpbmNvbWUgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgQ291bnQgb2YgYWNjZXNzIHRvIHJlc291cmNlcyBieSBmYW1pbHkgaW5jb21lDQp0YWJsZShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcywgc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUpDQoNCiMgQmFyIHBsb3Qgb2YgYWNjZXNzIHRvIHJlc291cmNlcyBieSBmYW1pbHkgaW5jb21lDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KYmFycGxvdCh0YWJsZShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlc1tzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTG93Il0pLCBtYWluID0gIkxvdyBGYW1pbHkgSW5jb21lIiwgeGxhYiA9ICJBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpiYXJwbG90KHRhYmxlKHN0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJNZWRpdW0iXSksIG1haW4gPSAiTWVkaXVtIEZhbWlseSBJbmNvbWUiLCB4bGFiID0gIkFjY2VzcyB0byBSZXNvdXJjZXMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmJhcnBsb3QodGFibGUoc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXNbc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIkhpZ2giXSksIG1haW4gPSAiSGlnaCBGYW1pbHkgSW5jb21lIiwgeGxhYiA9ICJBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KLSAqKkxvdyBJbmNvbWUgRmFtaWxpZXMqKjogU3R1ZGVudHMgZnJvbSBMb3cgSW5jb21lIGZhbWlsaWVzIHRlbmQgdG8gaGF2ZSB0aGUgbGFyZ2VzdCBjb3VudHMgaW4gTWVkaXVtIEFjY2VzcyB0byBSZXNvdXJjZXMgKDEyNjcgc3R1ZGVudHMpLCBzdWdnZXN0aW5nIG1vZGVyYXRlIGFjY2VzcyB0byByZXNvdXJjZXMgZXZlbiBmb3IgbG93ZXItaW5jb21lIGdyb3Vwcy4NCi0gKipIaWdoIEluY29tZSBGYW1pbGllcyoqOiBTdHVkZW50cyBmcm9tIEhpZ2ggSW5jb21lIGZhbWlsaWVzIGFyZSBtb3JlIGxpa2VseSB0byBoYXZlIEhpZ2ggQWNjZXNzIHRvIFJlc291cmNlcyAoMzY5IHN0dWRlbnRzKSB0aGFuIExvdyBBY2Nlc3MgdG8gUmVzb3VyY2VzICgyMzcgc3R1ZGVudHMpLg0KLSAqKk1lZGl1bSBJbmNvbWUgRmFtaWxpZXMqKjogU3R1ZGVudHMgZnJvbSBNZWRpdW0gSW5jb21lIGZhbWlsaWVzIGRvbWluYXRlIHRoZSBNZWRpdW0gQWNjZXNzIHRvIFJlc291cmNlcyBjYXRlZ29yeSAoMTMxMyBzdHVkZW50cyksIGluZGljYXRpbmcgYSBiYWxhbmNlZCBhdmFpbGFiaWxpdHkgb2YgcmVzb3VyY2VzLg0KDQojIyMgVGhlIHByb3BvcnRpb24gb2Ygc3R1ZGVudHMgd2l0aCBhY2Nlc3MgdG8gZWR1Y2F0aW9uYWwgcmVzb3VyY2VzIGJ5IFBhcmVudGFsIEVkdWNhdGlvbiBMZXZlbCBDYXRlZ29yeQ0KDQpXZSBub3cgZXhwbG9yZSB0aGUgcHJvcG9ydGlvbiBvZiBzdHVkZW50cyB3aXRoIGFjY2VzcyB0byBlZHVjYXRpb25hbCByZXNvdXJjZXMgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscy4NCg0KYGBge3J9DQojIENvdW50IG9mIGFjY2VzcyB0byByZXNvdXJjZXMgYnkgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsDQp0YWJsZShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcywgc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCkNCg0KIyBCYXIgcGxvdCBvZiBhY2Nlc3MgdG8gcmVzb3VyY2VzIGJ5IHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbA0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmJhcnBsb3QodGFibGUoc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXNbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiSGlnaCBTY2hvb2wiXSksIG1haW4gPSAiSGlnaCBTY2hvb2wgRWR1Y2F0aW9uIiwgeGxhYiA9ICJBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpiYXJwbG90KHRhYmxlKHN0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiXSksIG1haW4gPSAiQ29sbGVnZSBFZHVjYXRpb24iLCB4bGFiID0gIkFjY2VzcyB0byBSZXNvdXJjZXMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmJhcnBsb3QodGFibGUoc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXNbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiUG9zdGdyYWR1YXRlIl0pLCBtYWluID0gIlBvc3RncmFkdWF0ZSBFZHVjYXRpb24iLCB4bGFiID0gIkFjY2VzcyB0byBSZXNvdXJjZXMiLCB5bGFiID0gIkZyZXF1ZW5jeSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQotICoqSGlnaCBTY2hvb2wgRWR1Y2F0aW9uKio6IFBhcmVudHMgd2l0aCBIaWdoIFNjaG9vbCBlZHVjYXRpb24gaGF2ZSB0aGUgaGlnaGVzdCBjb3VudHMgaW4gYWxsIGFjY2VzcyBsZXZlbHMsIHBhcnRpY3VsYXJseSBNZWRpdW0gQWNjZXNzIHRvIFJlc291cmNlcyAoMTU1MCBzdHVkZW50cykuIFRoaXMgc3VnZ2VzdHMgdGhhdCBhIHNpZ25pZmljYW50IG51bWJlciBvZiBzdHVkZW50cyB3aXRoIHBhcmVudHMgaW4gdGhpcyBjYXRlZ29yeSBleHBlcmllbmNlIG1vZGVyYXRlIGFjY2VzcyB0byByZXNvdXJjZXMuDQotICoqQ29sbGVnZSBFZHVjYXRpb24qKjogU3R1ZGVudHMgd2hvc2UgcGFyZW50cyBoYXZlIENvbGxlZ2UgZWR1Y2F0aW9uIG1vc3RseSBmYWxsIGludG8gdGhlIE1lZGl1bSBBY2Nlc3MgdG8gUmVzb3VyY2VzIGNhdGVnb3J5ICgxMDA0IHN0dWRlbnRzKS4gQSBjb25zaWRlcmFibGUgcHJvcG9ydGlvbiBhbHNvIGhhdmUgSGlnaCBBY2Nlc3MgdG8gUmVzb3VyY2VzICg1NjQgc3R1ZGVudHMpLg0KLSAqKlBvc3RncmFkdWF0ZSBFZHVjYXRpb24qKjogU3R1ZGVudHMgd2l0aCBwYXJlbnRzIHdobyBoYXZlIGEgUG9zdGdyYWR1YXRlIGVkdWNhdGlvbiBzaG93IGEgaGlnaGVyIGxpa2VsaWhvb2Qgb2YgSGlnaCBBY2Nlc3MgdG8gUmVzb3VyY2VzICgzNzMgc3R1ZGVudHMpIGNvbXBhcmVkIHRvIExvdyBBY2Nlc3MgdG8gUmVzb3VyY2VzICgyNTggc3R1ZGVudHMpLg0KDQojIFRoZSB2YXJpYXRpb24gaW4gc2xlZXAgaG91cnMgYWNyb3NzIGRpZmZlcmVudCBsZXZlbHMgb2YgZXh0cmFjdXJyaWN1bGFyIHBhcnRpY2lwYXRpb24NCg0KV2Ugbm93IGFuYWx5emUgdGhlIHZhcmlhdGlvbiBpbiBzbGVlcCBob3VycyBhY3Jvc3MgZGlmZmVyZW50IGxldmVscyBvZiBleHRyYWN1cnJpY3VsYXIgcGFydGljaXBhdGlvbi4gQnV0IGZpcnN0IHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzbGVlcGluZyBob3Vycy4NCg0KYGBge3J9DQpzbGVlcF9ocnNfZGF0YSA8LSBzdHVkZW50X2RhdGEkU2xlZXBfSG91cnMNCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHNsZWVwaW5nIGhvdXJzDQpzdW1tYXJ5KHNsZWVwX2hyc19kYXRhKQ0KDQojIEhpc3RvZ3JhbSBvZiBzbGVlcGluZyBob3Vycw0KaGlzdChzbGVlcF9ocnNfZGF0YSwgbWFpbiA9ICJEaXN0cmlidXRpb24gb2YgU2xlZXBpbmcgSG91cnMiLCB4bGFiID0gIlNsZWVwaW5nIEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIFNoYXBpcm8tV2lsayB0ZXN0IGZvciBub3JtYWxpdHkNCnNoYXBpcm8udGVzdChzbGVlcF9ocnNfZGF0YVtzYW1wbGUobGVuZ3RoKHNsZWVwX2hyc19kYXRhKSwgcm91bmQobGVuZ3RoKHNsZWVwX2hyc19kYXRhKSpzYW1wbGVfZnJhY3Rpb24pKV0pDQpgYGANCg0KRnJvbSB0aGUgaGlzdG9ncmFtIHRoZSBkaXN0cmlidXRpb24gYXBwZWFycyB0byBiZSBub3JtYWxseSBkaXN0cmlidXRlZCB3aXRoIGhvdXJzIHJhbmdpbmcgZnJvbSAqKmA0YCoqIHRvICoqYDEwYCoqLiBIb3dldmVyLCB0aGUgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eSBzaG93cyB0aGF0IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KIyMjIFZhcmlhdGlvbiBpbiBzbGVlcCBob3VycyBhY3Jvc3MgZGlmZmVyZW50IGxldmVscyBvZiBleHRyYWN1cnJpY3VsYXIgcGFydGljaXBhdGlvbg0KDQpXZSBub3cgYW5hbHl6ZSB0aGUgdmFyaWF0aW9uIGluIHNsZWVwIGhvdXJzIGFjcm9zcyBkaWZmZXJlbnQgbGV2ZWxzIG9mIGV4dHJhY3VycmljdWxhciBwYXJ0aWNpcGF0aW9uLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpwYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfc2xlZXAgPC0gc3R1ZGVudF9kYXRhJFNsZWVwX0hvdXJzW3N0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiWWVzIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIlllcyIpLCByb3VuZChzdW0oc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJZZXMiKSpzYW1wbGVfZnJhY3Rpb24pKV0NCmRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfc2xlZXAgPC0gc3R1ZGVudF9kYXRhJFNsZWVwX0hvdXJzW3N0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiTm8iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiTm8iKSwgcm91bmQoc3VtKHN0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiTm8iKSpzYW1wbGVfZnJhY3Rpb24pKV0NCg0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHNsZWVwIGhvdXJzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQpzdW1tYXJ5KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9zbGVlcCkNCnN1bW1hcnkoZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9zbGVlcCkNCg0KIyBIaXN0b2dyYW0gb2Ygc2xlZXAgaG91cnMgYnkgZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpoaXN0KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9zbGVlcCwgbWFpbiA9ICJFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyIsIHhsYWIgPSAiU2xlZXAgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfc2xlZXAsIG1haW4gPSAiTm8gRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMiLCB4bGFiID0gIlNsZWVwIEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIFdpbGNveG9uIHJhbmsgc3VtIHRlc3QNCndpbGNveC50ZXN0KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9zbGVlcCwgZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9zbGVlcCkNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg==